@stacksjs/ts-cloud 0.12.4 → 0.12.6
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/bin/{chunk-yw55bzp0.js → chunk-j91jb1nx.js} +1 -1
- package/dist/bin/{chunk-dm06r9kd.js → chunk-xdqq98wp.js} +50 -47
- package/dist/bin/{chunk-wygaj04z.js → chunk-z3qz1713.js} +1 -1
- package/dist/bin/cli.js +4 -4
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-v8rd7tpx.js → chunk-fxxjtz86.js} +1 -1
- package/dist/{chunk-xdpy9p7n.js → chunk-kp6mgc9b.js} +71 -68
- package/dist/deploy/index.js +1 -1
- package/dist/drivers/hetzner/driver.d.ts +14 -0
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/shared/remote-exec.d.ts +19 -0
- package/dist/index.js +2 -2
- 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 +6 -6
- 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 +6 -6
- 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 +6 -6
- 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 +2 -2
- 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 +2 -2
- 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 +5 -5
- 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 +5 -5
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Oe as a,Pe as b,Qe as c,Re as d,Se as e,Te as f,Ue as g,Ve as h,We as i,Xe as j}from"./chunk-
|
|
1
|
+
import{Oe as a,Pe as b,Qe as c,Re as d,Se as e,Te as f,Ue as g,Ve as h,We as i,Xe as j}from"./chunk-xdqq98wp.js";import"./chunk-rtecnmts.js";import"./chunk-8ewncfce.js";import"./chunk-9kf0np8j.js";import"./chunk-xk08030d.js";import"./chunk-x6f61g36.js";import"./chunk-xhwqpgwq.js";import"./chunk-a7w13qfm.js";import"./chunk-btsyjhk7.js";import"./chunk-ja1vjdn1.js";import"./chunk-4q6tad44.js";import"./chunk-ehc63fvs.js";export{d as mergeDiscoveredSites,b as metricsScript,c as parseBlock,h as parseDeployHistory,f as parseServerLogs,g as parseServerSecurity,i as resolveConfigOnlyServerDashboardData,j as resolveServerDashboardData,e as serverLogSources,a as sharedBoxProbeScript};
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import{i as tr,j as Oi,k as wn,l as Li,n as ji,o as pl}from"./chunk-xkfrqqcs.js";import{v as mr}from"./chunk-b4wt9jcg.js";import{$ as oc,A as Gr,Aa as gl,B as xs,Ba as hl,C as Zs,Ca as xo,D as oa,Da as yl,E as zn,Ea as Ne,F as qn,Fa as Ul,G as et,Ga as Qt,H as Na,Ha as bd,I as ja,Ia as wd,J as Fa,Ja as Sd,K as Ma,Ka as ps,L as Ba,La as fs,M as _a,Ma as Cd,N as za,Na as od,O as Ua,Oa as sd,P as qe,Pa as ad,Q as Ya,Qa as Go,R as Jn,Ra as Le,S as vi,Sa as Ye,T as Za,Ta as ct,U as Qa,Ua as cs,V as Xa,Va as pd,W as ec,Wa as vr,X as tc,Y as nc,Z as rc,_ as ic,aa as bi,ba as Yn,ca as rr,da as Rc,ea as Ic,fa as Ui,ga as Pc,ha as xc,ia as Dc,ja as Tc,ka as qi,la as Nc,ma as Oc,na as Lc,oa as jc,pa as hd,qa as yd,ra as vd,sa as Yc,ta as Zc,ua as Qc,va as ko,w as Tt,wa as Ro,x as le,xa as fl,y as _l,ya as Io,z as q,za as Po}from"./chunk-
|
|
2
|
+
import{i as tr,j as Oi,k as wn,l as Li,n as ji,o as pl}from"./chunk-xkfrqqcs.js";import{v as mr}from"./chunk-b4wt9jcg.js";import{$ as oc,A as Gr,Aa as gl,B as xs,Ba as hl,C as Zs,Ca as xo,D as oa,Da as yl,E as zn,Ea as Ne,F as qn,Fa as Ul,G as et,Ga as Qt,H as Na,Ha as bd,I as ja,Ia as wd,J as Fa,Ja as Sd,K as Ma,Ka as ps,L as Ba,La as fs,M as _a,Ma as Cd,N as za,Na as od,O as Ua,Oa as sd,P as qe,Pa as ad,Q as Ya,Qa as Go,R as Jn,Ra as Le,S as vi,Sa as Ye,T as Za,Ta as ct,U as Qa,Ua as cs,V as Xa,Va as pd,W as ec,Wa as vr,X as tc,Y as nc,Z as rc,_ as ic,aa as bi,ba as Yn,ca as rr,da as Rc,ea as Ic,fa as Ui,ga as Pc,ha as xc,ia as Dc,ja as Tc,ka as qi,la as Nc,ma as Oc,na as Lc,oa as jc,pa as hd,qa as yd,ra as vd,sa as Yc,ta as Zc,ua as Qc,va as ko,w as Tt,wa as Ro,x as le,xa as fl,y as _l,ya as Io,z as q,za as Po}from"./chunk-j91jb1nx.js";import"./chunk-sj5csg49.js";import{$a as _c,Ab as md,Ac as bc,Bb as qo,Db as hc,Eb as Mi,Jc as wc,Mc as Sc,Sc as Ge,Wc as Cc,Xc as Bi,Yc as _i,Za as We,Zc as $c,ab as zc,bb as Uc,bc as yc,cb as Vc,cc as vc,db as Wc,eb as qc,fb as Gc,gb as Kc,hb as Hc,ib as Jl,jb as Yl,lb as Zl,mb as Ql,nb as Jc,ob as ar,pb as Ms,qb as or,sb as Sn,tb as Vo,ub as Wo,vb as ds,wb as dd,xb as ud}from"./chunk-tfbs8k8v.js";import{fd as Dt}from"./chunk-s4yzes15.js";import{gd as Hn}from"./chunk-3aph4c1w.js";import{hd as ci,id as li,jd as gn,kd as vo,ld as bo,nd as di,od as ui,pd as mi,qd as pi,rd as vt,td as fi,ud as Ie,vd as Or}from"./chunk-mfrf9q4b.js";import{wd as ne}from"./chunk-82mj52xr.js";import"./chunk-7zhgmp1s.js";import{Bd as rt,Cd as qt,Dd as uc,Ed as mc,Fd as Et}from"./chunk-e2bybahr.js";import{Hd as at}from"./chunk-d7ke90zt.js";import{Id as pt,Jd as bt,Nd as Bc}from"./chunk-kg61p5hw.js";import{_d as nt}from"./chunk-c0bdafbx.js";import{$d as jr,Ae as Ia,Be as Pa,Ce as xa,De as Ea,Ee as Da,Fe as ht,Ge as Ta,Ie as $o,Je as Ao,ae as wo,be as _t,ce as co,de as sn,ee as Br,fe as ga,ge as na,he as uo,ie as ra,je as Zr,ke as ia,le as Yr,me as un,ne as Vt,oe as Wt,pe as wa,qe as Sa,re as Rt,se as Ca,te as He,ue as Qr,ve as $a,we as Xr,xe as Aa,ye as ka,ze as Ra}from"./chunk-xdqq98wp.js";import{Ye as Ae}from"./chunk-rtecnmts.js";import{af as Ni}from"./chunk-8ewncfce.js";import{if as Ti}from"./chunk-9kf0np8j.js";import"./chunk-xk08030d.js";import{Af as So,Bf as Co,Cf as ul,Df as ml,Kf as Xs,Nf as ea,Rf as ta,vf as Qs,yf as Pn,zf as ho}from"./chunk-x6f61g36.js";import"./chunk-xhwqpgwq.js";import{jg as ie}from"./chunk-a7w13qfm.js";import{kg as he,lg as Je}from"./chunk-my3ewh3a.js";import{og as Kn}from"./chunk-e5ab5twy.js";import{pg as lc,qg as de}from"./chunk-btsyjhk7.js";import{rg as Ds,ug as Ts,vg as Ns,wg as Os,xg as Ls,yg as js,zg as Fs}from"./chunk-w32xv8n4.js";import{Ag as hr,Eg as cd,Fg as zl}from"./chunk-dz1ec589.js";import"./chunk-mcr0r4at.js";import{Ig as xn}from"./chunk-9a88fp00.js";import{$g as Fl,Jg as lt,Kg as al,Lg as h,Mg as f,Ng as R,Og as hn,Pg as a,Qg as M,Rg as S,Sg as A,Tg as Z,Ug as O,Vg as Tr,Wg as x,Xg as Dn,Yg as Xe,Zg as Ll,_g as jl,ah as Ml,bh as z}from"./chunk-6tfwm33r.js";import{dh as Ii,fh as sl}from"./chunk-ja1vjdn1.js";import{$h as Mc,Ai as ma,Ch as Cl,Di as pa,Eh as In,Fh as go,Gh as _n,Ji as fa,Ki as Wn,Lh as Yt,Mh as sa,Qi as Il,Rh as aa,Sh as ca,Vh as we,Vi as Pl,Wh as cl,Xh as ll,Yh as dl,fi as zr,ji as Ur,ki as me,li as la,mi as Un,ni as ft,qi as Vr,vi as da,wi as zt,xi as Vn,yi as Wr,zi as ua}from"./chunk-4q6tad44.js";import{op as F}from"./chunk-ehc63fvs.js";import{existsSync as $d}from"node:fs";import Cr from"node:fs/promises";import ys from"node:os";import $r from"node:path";import At from"node:process";import{EventEmitter as Ad}from"node:events";import ut from"node:process";import vs from"node:process";import Rr from"node:process";import On from"node:process";import nn from"node:process";import Cs from"node:tty";import mu,{stdin as rg,stdout as ig}from"node:process";class $s{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let r=ys.homedir(),e=$r.join(r,".config","clapp");this.configPath=$r.join(e,"telemetry.json")}async isEnabled(){if(At.env.DO_NOT_TRACK==="1"||At.env.DO_NOT_TRACK==="true")return!1;if(At.env.NO_TELEMETRY==="1"||At.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let r=await this.loadConfig();if(r.enabled=!0,!r.userId)r.userId=this.generateUserId();await this.saveConfig(r)}async disable(){let r=await this.loadConfig();r.enabled=!1,await this.saveConfig(r)}async track(r,e){if(!await this.isEnabled())return;let n={event:r,...e,timestamp:Date.now(),platform:ys.platform(),nodeVersion:At.version};if(this.events.push(n),this.events.length>=10)await this.send()}async trackCommand(r,e){await this.track("command",{command:r,duration:e})}async trackError(r,e){await this.track("error",{error:r,command:e})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let e=await this.loadConfig();return e.lastSent=Date.now(),await this.saveConfig(e),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let e=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(e),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(r){return new Promise((e)=>setTimeout(e,r))}async status(){let r=await this.loadConfig();return{enabled:r.enabled,doNotTrack:At.env.DO_NOT_TRACK==="1"||At.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:r.lastSent}}async loadConfig(){if(this.config)return this.config;try{if($d(this.configPath)){let r=await Cr.readFile(this.configPath,"utf-8");return this.config=JSON.parse(r),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig(r){this.config=r;try{let e=$r.dirname(this.configPath);await Cr.mkdir(e,{recursive:!0}),await Cr.writeFile(this.configPath,JSON.stringify(r,null,2),"utf-8")}catch{}}generateUserId(){let r=Math.random().toString(36).substring(2,15),e=Date.now().toString(36);return`${r}-${e}`}}var Wf=new $s;function kr(r){return r.replace(/[<[].+/,"").trim()}function kd(r){let e=/<([^>]+)>/g,t=/\[([^\]]+)\]/g,n=[],i=(c)=>{let l=!1,d=c[1];if(d.startsWith("..."))d=d.slice(3),l=!0;return{required:c[0].startsWith("<"),value:d,variadic:l}},o;while(o=e.exec(r))n.push(i(o));let s;while(s=t.exec(r))n.push(i(s));return n}function Rd(r){let e={alias:{},boolean:[]};for(let[t,n]of r.entries()){if(n.names.length>1)e.alias[n.names[0]]=n.names.slice(1);if(n.isBoolean)if(n.negated){if(!r.some((o,s)=>s!==t&&o.names.some((c)=>n.names.includes(c))&&typeof o.required==="boolean"))e.boolean.push(n.names[0])}else e.boolean.push(n.names[0])}return e}function bs(r){return r.reduce((e,t)=>e.length>=t.length?e:t,"")}function Ar(r,e){return r.length>=e?r:`${r}${" ".repeat(e-r.length)}`}function Nn(r){return r.replace(/([a-z])-([a-z])/g,(e,t,n)=>t+n.toUpperCase())}function Id(r,e,t){let n=0,i=e.length,o=r,s;for(;n<i;++n)s=o[e[n]],o=o[e[n]]=n===i-1?t:s!=null?s:!!~e[n+1].indexOf(".")||!(+e[n+1]>-1)?{}:[]}function Pd(r,e){for(let t of Object.keys(e)){let n=e[t];if(n.shouldTransform){if(r[t]=Array.prototype.concat.call([],r[t]),typeof n.transformFunction==="function")r[t]=r[t].map(n.transformFunction)}}}function xd(r){let e=/([^\\/]+)$/.exec(r);return e?e[1]:""}function rn(r){return r.split(".").map((e,t)=>t===0?Nn(e):e).join(".")}class on extends Error{exitCode=2;isUsageError=!0;usage;constructor(r,e){super(r);if(this.name=this.constructor.name,e!==void 0)this.usage=e;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(r).stack}format(r=!1){if(r&&this.stack)return`${this.message}
|
|
3
3
|
|
|
4
4
|
Stack trace:
|
|
5
5
|
${this.stack}`;return this.message}}function Ed(r){if(r instanceof on)return!0;return!!r&&typeof r==="object"&&r.name==="ClappError"&&typeof r.message==="string"}function Dd(){let{env:r}=vs,{TERM:e,TERM_PROGRAM:t}=r;if(vs.platform!=="win32")return e!=="linux";return Boolean(r.WT_SESSION)||Boolean(r.TERMINUS_SUBLIME)||r.ConEmuTask==="{cmd::Cmder}"||t==="Terminus-Sublime"||t==="vscode"||e==="xterm-256color"||e==="alacritty"||e==="rxvt-unicode"||e==="rxvt-unicode-256color"||r.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var Ln="\x1B",re=`${Ln}[`;var ws={to(r,e){if(!e)return`${re}${r+1}G`;return`${re}${e+1};${r+1}H`},move(r,e){let t="";if(r<0)t+=`${re}${-r}D`;else if(r>0)t+=`${re}${r}C`;if(e<0)t+=`${re}${-e}A`;else if(e>0)t+=`${re}${e}B`;return t},up:(r=1)=>`${re}${r}A`,down:(r=1)=>`${re}${r}B`,forward:(r=1)=>`${re}${r}C`,backward:(r=1)=>`${re}${r}D`,nextLine:(r=1)=>`${re}E`.repeat(r),prevLine:(r=1)=>`${re}F`.repeat(r),left:`${re}G`,hide:`${re}?25l`,show:`${re}?25h`,save:`${Ln}7`,restore:`${Ln}8`};var Hf={screen:`${re}2J`,up:(r=1)=>`${re}1J`.repeat(r),down:(r=1)=>`${re}J`.repeat(r),line:`${re}2K`,lineEnd:`${re}K`,lineStart:`${re}1K`,lines(r){let e="";for(let t=0;t<r;t++)e+=this.line+(t<r-1?ws.up():"");if(r)e+=ws.left;return e}},Jf={screen:`${Ln}c`};function Td(r,e){let t=[];for(let n=0;n<=e.length;n++)t[n]=[n];for(let n=0;n<=r.length;n++)t[0][n]=n;for(let n=1;n<=e.length;n++)for(let i=1;i<=r.length;i++)if(e.charAt(n-1)===r.charAt(i-1))t[n][i]=t[n-1][i-1];else t[n][i]=Math.min(t[n-1][i-1]+1,t[n][i-1]+1,t[n-1][i]+1);return t[e.length][r.length]}function As(r,e,t=2,n=3){return e.map((i)=>({cmd:i,distance:Td(r,i)})).filter(({distance:i})=>i<=t).sort((i,o)=>i.distance-o.distance).slice(0,n).map(({cmd:i})=>i)}function Nd(r,e={}){let t={_:[]},n=e.alias||{},i=new Set(e.boolean||[]),o={};for(let l of Object.keys(n))for(let d of n[l])o[d]=l;for(let l of i)if(n[l])for(let d of n[l])i.add(d);function s(l,d){if(l===void 0)return d;if(typeof d==="boolean")return d;return Array.isArray(l)?[...l,d]:[l,d]}function c(l,d){let u=o[l]||l,m=s(t[u],d);if(t[u]=m,n[u])for(let p of n[u])t[p]=m;if(o[l]&&n[o[l]])for(let p of n[o[l]])t[p]=m;t[l]=m}for(let l=0;l<r.length;l++){let d=r[l];if(d==="--"){t._.push(...r.slice(l+1));break}if(d.startsWith("--")){let u=d.indexOf("=");if(u!==-1){let m=Nn(d.slice(2,u)),p=d.slice(u+1);c(m,p)}else{let m=d.slice(2);if(m.startsWith("no-")){let w=Nn(m.slice(3));c(w,!1);continue}let p=Nn(m),y=o[p]||p;if(i.has(y)||i.has(p))c(p,!0);else{let w=r[l+1];if(w!==void 0&&!w.startsWith("-"))c(p,w),l++;else c(p,!0)}}}else if(d.startsWith("-")&&d.length>1){let u=d.slice(1);for(let m=0;m<u.length;m++){let p=u[m],y=o[p]||p;if(m===u.length-1&&!i.has(y)&&!i.has(p)){let w=r[l+1];if(w!==void 0&&!w.startsWith("-"))c(p,w),l++;else c(p,!0)}else c(p,!0)}}else t._.push(d)}return t}class ks{rawName;description;name;names;isBoolean;required;config;negated;constructor(r,e,t){if(this.rawName=r,this.description=e,this.config=Object.assign({},t),r=r.replace(/\.\*/g,""),this.negated=!1,this.names=kr(r).split(",").map((n)=>{let i=n.trim().replace(/^-{1,2}/,"");if(i.startsWith("no-"))this.negated=!0,i=i.replace(/^no-/,"");return rn(i)}).sort((n,i)=>n.length>i.length?1:-1),this.name=this.names[this.names.length-1],this.negated&&this.config.default==null)this.config.default=!0;if(r.includes("<"))this.required=!0;else if(r.includes("["))this.required=!1;else this.isBoolean=!0}}var Zf=Rr.argv,Od=`${Rr.platform}-${Rr.arch} bun-v${typeof Bun<"u"?Bun.version:"unknown"}`,Ss=On.argv,Ld=`${On.platform}-${On.arch} node-${On.version}`;class Ir{rawName;description;config;cli;options;aliasNames;name;namespace;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;beforeHooks;afterHooks;middleware;constructor(r,e,t,n){this.rawName=r,this.description=e,this.config=t,this.cli=n,this.options=[],this.aliasNames=[],this.name=kr(r);let i=kr(r),o=i.indexOf(":");if(o>0)this.namespace=i.substring(0,o),this.name=i.substring(o+1);if(this.args=kd(r),this.examples=[],this.beforeHooks=[],this.afterHooks=[],this.middleware=[],!t)this.config={}}usage(r){return this.usageText=r,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(r,e="-v, --version"){return this.versionNumber=r,this.option(e,"Display version number"),this}example(r){return this.examples.push(r),this}option(r,e,t){let n=new ks(r,e,t);return this.options.push(n),this}alias(r){return this.aliasNames.push(r),this}action(r){return this.commandAction=r,this}before(r){return this.beforeHooks.push(r),this}after(r){return this.afterHooks.push(r),this}use(r){return this.middleware.push(r),this}isMatched(r){if(this.aliasNames.includes(r))return!0;if(this.namespace)return`${this.namespace}:${this.name}`===r;return this.name===r}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof Pr}get displayName(){return this.namespace?`${this.namespace}:${this.name}`:this.name}hasOption(r){let e=rn(r.split(".")[0]);return!!this.options.find((t)=>t.names.some((n)=>rn(n)===e))}outputHelp(){let{name:r,commands:e}=this.cli,{versionNumber:t,options:n,helpCallback:i}=this.cli.globalCommand,o=[{body:`${r}${t?`/${t}`:""}`}];if(o.push({title:"Usage",body:` $ ${r} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&e.length>0){let d=bs(e.map((w)=>w.rawName)),u=new Map,m=[];for(let w of e)if(w.namespace){if(!u.has(w.namespace))u.set(w.namespace,[]);u.get(w.namespace).push(w)}else m.push(w);let p="";if(m.sort((w,g)=>w.rawName<g.rawName?-1:w.rawName>g.rawName?1:0),m.length>0)p+=m.map((w)=>` ${Ar(w.rawName,d.length)} ${w.description}`).join(`
|
|
@@ -28,7 +28,7 @@ Received ${t}, cleaning up...`),r)try{await r()}catch(n){console.error("Error du
|
|
|
28
28
|
`)),this.enableDidYouMean){let e=[];for(let n of this.commands){if(n.displayName)e.push(n.displayName);if(n.aliasNames)e.push(...n.aliasNames)}let t=As(r,e);if(t.length>0)console.log(tn.yellow("Did you mean one of these?")),t.forEach((n)=>console.log(` ${tn.dim("•")} ${this.name} ${n}`)),console.log("")}console.log(tn.dim("Run"),`${this.name} --help`,tn.dim("to see all available commands")),ut.exit(1)}async parse(r=Ss,e={}){let{run:t=!0,exitOnError:n=!1}=e;if(n)try{return await this.parse(r,{run:t})}catch(l){throw this.handleUsageError(l),l}if(this.rawArgs=r,!this.name)this.name=r[1]?xd(r[1]):"cli";let i=!0,o=r.slice(2),s=o[0];if(s&&!s.startsWith("-")){for(let l of this.commands)if(l.isMatched(s)){let d=this.mri(o,l);i=!1;let u={...d,args:d.args.slice(1)};this.setParsedInfo(u,l,s),this.emit(`command:${s}`,l);break}if(i){let l=o[1];if(l&&!l.startsWith("-")){let d=`${s}:${l}`;for(let u of this.commands)if(u.isMatched(d)){let m=this.mri(o,u);i=!1;let p={...m,args:m.args.slice(2)};this.setParsedInfo(p,u,d),this.emit(`command:${d}`,u);break}}}}if(i){for(let l of this.commands)if(l.name===""){i=!1;let d=this.mri(o,l);this.setParsedInfo(d,l),this.emit("command:!",l);break}}if(i){let l=this.mri(r.slice(2));this.setParsedInfo(l)}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(),t=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),t=!1,this.unsetMatchedCommand();let c={args:this.args,options:this.options};if(t)await this.runMatchedCommand();if(!this.matchedCommand&&this.args[0]){if(this.emit("command:*"),!(this.listenerCount("command:*")>0))this.showCommandNotFound(this.args[0])}return c}mri(r,e){let t=[...this.globalCommand.options,...e?e.options:[]],n=Rd(t),i=[],o=r.indexOf("--");if(o>-1)i=r.slice(o+1),r=r.slice(0,o);let s=Nd(r,n),c={_:s._};for(let p of Object.keys(s))if(p!=="_")c[rn(p)]=s[p];let l=c._,d={"--":i},u=e&&e.config.ignoreOptionDefaultValue?e.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,m=Object.create(null);for(let p of t){if(!u&&p.config.default!==void 0)for(let y of p.names)d[y]=p.config.default;if(Array.isArray(p.config.type)){if(m[p.name]===void 0)m[p.name]={shouldTransform:!0,transformFunction:p.config.type[0]}}}for(let p of Object.keys(c))if(p!=="_"){let y=p.split(".");Id(d,y,c[p]),Pd(d,m)}return{args:l,options:d}}async run(r=Ss){return this.parse(r,{run:!0,exitOnError:!0})}handleUsageError(r){if(!Ed(r)||r.isUsageError===!1)return;let e=r.message||"command-line error",t=this.name?`${this.name}: `:"",n=/--help/.test(e)?"":r.usage?`
|
|
29
29
|
Usage: ${r.usage}`:`
|
|
30
30
|
Run \`${this.name??"cli"} --help\` for usage.`;ut.stderr.write(`${t}${e}${n}
|
|
31
|
-
`),ut.exit(r.exitCode??2)}async runMatchedCommand(){let{args:r,options:e,matchedCommand:t}=this;if(!t||!t.commandAction)return;t.checkUnknownOptions(),t.checkOptionValue(),t.checkRequiredArgs();let n=[];t.args.forEach((c,l)=>{if(c.variadic)n.push(r.slice(l));else n.push(r[l])}),n.push(e);let i={command:t,args:n,options:e};for(let c of t.beforeHooks)await c(i);let o,s=async()=>{let c=t.commandAction.apply(this,n);if(c instanceof Promise)o=await c;else o=c;return o};if(t.middleware.length>0){let c=0,l=async()=>{if(c<t.middleware.length){let d=t.middleware[c++];await d({...i,next:l})}else await s()};await l()}else await s();for(let c of t.afterHooks)await c(i);return o}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ut.removeAllListeners("SIGINT"),ut.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 Rs{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(r){if(!this.enabled){this.misses++;return}let e=this.cache.get(r);if(!e){this.misses++;return}if(Date.now()-e.timestamp>e.ttl){this.cache.delete(r),this.misses++;return}return this.hits++,e.value}set(r,e,t=5000){if(!this.enabled)return;this.cache.set(r,{value:e,timestamp:Date.now(),ttl:t})}has(r){if(!this.enabled)return!1;let e=this.cache.get(r);if(!e)return!1;if(Date.now()-e.timestamp>e.ttl)return this.cache.delete(r),!1;return!0}delete(r){this.cache.delete(r)}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 r=Date.now();for(let[e,t]of this.cache.entries())if(r-t.timestamp>t.ttl)this.cache.delete(e)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Xf=new Rs;function Bd(){if("FORCE_COLOR"in nn.env)return nn.env.FORCE_COLOR!=="0";if("NO_COLOR"in nn.env||nn.env.TERM==="dumb")return!1;if(nn.platform==="win32")return!0;return Cs.isatty(1)&&Cs.isatty(2)}var Is=Bd();function te(r,e){if(!Is)return(t)=>t;return(t)=>r+t+e}var _d=te("\x1B[0m","\x1B[0m"),zd=te("\x1B[31m","\x1B[39m"),Ud=te("\x1B[32m","\x1B[39m"),Vd=te("\x1B[33m","\x1B[39m"),Wd=te("\x1B[34m","\x1B[39m"),qd=te("\x1B[35m","\x1B[39m"),Gd=te("\x1B[36m","\x1B[39m"),Kd=te("\x1B[37m","\x1B[39m"),Hd=te("\x1B[90m","\x1B[39m"),Jd=te("\x1B[1m","\x1B[22m"),Yd=te("\x1B[3m","\x1B[23m"),Zd=te("\x1B[4m","\x1B[24m"),Qd=te("\x1B[2m","\x1B[22m"),Xd=te("\x1B[7m","\x1B[27m"),eu=te("\x1B[8m","\x1B[28m"),tu=te("\x1B[9m","\x1B[29m"),nu=te("\x1B[41m","\x1B[49m"),ru=te("\x1B[42m","\x1B[49m"),iu=te("\x1B[43m","\x1B[49m"),ou=te("\x1B[44m","\x1B[49m"),su=te("\x1B[45m","\x1B[49m"),au=te("\x1B[46m","\x1B[49m"),cu=te("\x1B[47m","\x1B[49m"),lu=Is,du={reset:_d,red:zd,green:Ud,yellow:Vd,blue:Wd,magenta:qd,cyan:Gd,white:Kd,gray:Hd,bold:Jd,italic:Yd,underline:Zd,dim:Qd,inverse:Xd,hidden:eu,strikethrough:tu,bgRed:nu,bgGreen:ru,bgYellow:iu,bgBlue:ou,bgMagenta:su,bgCyan:au,bgWhite:cu,isColorSupported:lu},uu=du,pu=["up","down","left","right","space","enter","cancel"],og={actions:new Set(pu),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var sg=mu.platform.startsWith("win"),ag=Symbol("clapp:cancel");var fu=Dd();var ee=(r,e)=>fu?r:e,cg=ee("◆","*"),lg=ee("■","x"),dg=ee("▲","x"),ug=ee("◇","o"),mg=ee("┌","T"),gu=ee("│","|"),pg=ee("└","—"),fg=ee("●",">"),gg=ee("○"," "),hg=ee("◻","[•]"),yg=ee("◼","[+]"),vg=ee("◻","[ ]"),bg=ee("▪","•"),wg=ee("─","-"),Sg=ee("╮","+"),Cg=ee("├","+"),$g=ee("╯","+"),Ag=ee("●","•"),kg=ee("◆","*"),Rg=ee("▲","!"),Ig=ee("■","x");var Pg={light:ee("─","-"),heavy:ee("━","="),block:ee("█","#")};function hu(){return`${uu.gray(gu)} `}var xg=hu();var Er="0.12.
|
|
31
|
+
`),ut.exit(r.exitCode??2)}async runMatchedCommand(){let{args:r,options:e,matchedCommand:t}=this;if(!t||!t.commandAction)return;t.checkUnknownOptions(),t.checkOptionValue(),t.checkRequiredArgs();let n=[];t.args.forEach((c,l)=>{if(c.variadic)n.push(r.slice(l));else n.push(r[l])}),n.push(e);let i={command:t,args:n,options:e};for(let c of t.beforeHooks)await c(i);let o,s=async()=>{let c=t.commandAction.apply(this,n);if(c instanceof Promise)o=await c;else o=c;return o};if(t.middleware.length>0){let c=0,l=async()=>{if(c<t.middleware.length){let d=t.middleware[c++];await d({...i,next:l})}else await s()};await l()}else await s();for(let c of t.afterHooks)await c(i);return o}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ut.removeAllListeners("SIGINT"),ut.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 Rs{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(r){if(!this.enabled){this.misses++;return}let e=this.cache.get(r);if(!e){this.misses++;return}if(Date.now()-e.timestamp>e.ttl){this.cache.delete(r),this.misses++;return}return this.hits++,e.value}set(r,e,t=5000){if(!this.enabled)return;this.cache.set(r,{value:e,timestamp:Date.now(),ttl:t})}has(r){if(!this.enabled)return!1;let e=this.cache.get(r);if(!e)return!1;if(Date.now()-e.timestamp>e.ttl)return this.cache.delete(r),!1;return!0}delete(r){this.cache.delete(r)}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 r=Date.now();for(let[e,t]of this.cache.entries())if(r-t.timestamp>t.ttl)this.cache.delete(e)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Xf=new Rs;function Bd(){if("FORCE_COLOR"in nn.env)return nn.env.FORCE_COLOR!=="0";if("NO_COLOR"in nn.env||nn.env.TERM==="dumb")return!1;if(nn.platform==="win32")return!0;return Cs.isatty(1)&&Cs.isatty(2)}var Is=Bd();function te(r,e){if(!Is)return(t)=>t;return(t)=>r+t+e}var _d=te("\x1B[0m","\x1B[0m"),zd=te("\x1B[31m","\x1B[39m"),Ud=te("\x1B[32m","\x1B[39m"),Vd=te("\x1B[33m","\x1B[39m"),Wd=te("\x1B[34m","\x1B[39m"),qd=te("\x1B[35m","\x1B[39m"),Gd=te("\x1B[36m","\x1B[39m"),Kd=te("\x1B[37m","\x1B[39m"),Hd=te("\x1B[90m","\x1B[39m"),Jd=te("\x1B[1m","\x1B[22m"),Yd=te("\x1B[3m","\x1B[23m"),Zd=te("\x1B[4m","\x1B[24m"),Qd=te("\x1B[2m","\x1B[22m"),Xd=te("\x1B[7m","\x1B[27m"),eu=te("\x1B[8m","\x1B[28m"),tu=te("\x1B[9m","\x1B[29m"),nu=te("\x1B[41m","\x1B[49m"),ru=te("\x1B[42m","\x1B[49m"),iu=te("\x1B[43m","\x1B[49m"),ou=te("\x1B[44m","\x1B[49m"),su=te("\x1B[45m","\x1B[49m"),au=te("\x1B[46m","\x1B[49m"),cu=te("\x1B[47m","\x1B[49m"),lu=Is,du={reset:_d,red:zd,green:Ud,yellow:Vd,blue:Wd,magenta:qd,cyan:Gd,white:Kd,gray:Hd,bold:Jd,italic:Yd,underline:Zd,dim:Qd,inverse:Xd,hidden:eu,strikethrough:tu,bgRed:nu,bgGreen:ru,bgYellow:iu,bgBlue:ou,bgMagenta:su,bgCyan:au,bgWhite:cu,isColorSupported:lu},uu=du,pu=["up","down","left","right","space","enter","cancel"],og={actions:new Set(pu),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var sg=mu.platform.startsWith("win"),ag=Symbol("clapp:cancel");var fu=Dd();var ee=(r,e)=>fu?r:e,cg=ee("◆","*"),lg=ee("■","x"),dg=ee("▲","x"),ug=ee("◇","o"),mg=ee("┌","T"),gu=ee("│","|"),pg=ee("└","—"),fg=ee("●",">"),gg=ee("○"," "),hg=ee("◻","[•]"),yg=ee("◼","[+]"),vg=ee("◻","[ ]"),bg=ee("▪","•"),wg=ee("─","-"),Sg=ee("╮","+"),Cg=ee("├","+"),$g=ee("╯","+"),Ag=ee("●","•"),kg=ee("◆","*"),Rg=ee("▲","!"),Ig=ee("■","x");var Pg={light:ee("─","-"),heavy:ee("━","="),block:ee("█","#")};function hu(){return`${uu.gray(gu)} `}var xg=hu();var Er="0.12.6";import{existsSync as Dr}from"node:fs";import{mkdir as vu,writeFile as Ps}from"node:fs/promises";function Nr(r){r.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(e)=>{if(S("Initializing ts-cloud Project"),Dr("cloud.config.ts")){if(!await O("cloud.config.ts already exists. Overwrite?",!1)){a("Initialization cancelled");return}}let t=e?.name||await Z("Project name","my-app"),n=e?.mode||await Tr("Select deployment mode",["serverless","server"]),i=e?.region||await Tr("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),o=new A("Creating configuration file...");o.start();let s=`import { defineConfig } from '@ts-cloud/core'
|
|
32
32
|
|
|
33
33
|
export default defineConfig({
|
|
34
34
|
project: {
|
|
@@ -315,7 +315,7 @@ Resources to create: ${k}`);let T={};for(let E of Object.values(d.Resources||{})
|
|
|
315
315
|
No changes detected - infrastructure is up to date`);return}if(a(`
|
|
316
316
|
Changes detected:
|
|
317
317
|
`),b.length>0){h(`Resources to add (${b.length}):`);for(let C of b){let k=y[C].Type;a(` + ${C} (${k})`)}console.log()}if(I.length>0){f(`Resources to remove (${I.length}):`);for(let C of I){let k=p[C].Type;a(` - ${C} (${k})`)}console.log()}if(v.length>0){R(`Resources to modify (${v.length}):`);for(let C of v){let k=y[C].Type;a(` ~ ${C} (${k})`)}console.log()}a("Summary:"),a(` - Add: ${b.length}`),a(` - Remove: ${I.length}`),a(` - Modify: ${v.length}`),a("\nRun `cloud deploy` to apply these changes")}catch(t){f(`Diff failed: ${t.message}`)}})}function gt(r,e=0){let t=Number(r);return Number.isFinite(t)?t:e}function Hr(r){return gt(r)*1024}function Yu(r){let e=r?.date?.trim(),t=r?.time?.trim();if(!e||!t)return null;let n=new Date(`${e}T${t}Z`);return Number.isFinite(n.getTime())?n.toISOString():null}function Zu(r,e,t){let n;try{n=JSON.parse(r)}catch{return[]}let i=(n?.sysstat?.hosts??[]).flatMap((s)=>s.statistics??[]),o=[];for(let s of i){let c=Yu(s.timestamp);if(!c)continue;let l=new Date(c).getTime();if(l<e.getTime()||l>t.getTime())continue;let d=s["cpu-load"]?.find((m)=>m.cpu==="all")??s["cpu-load"]?.[0],u=gt(d?.idle,100);o.push({timestamp:c,cpuUsedPercent:Math.max(0,Math.min(100,100-u)),cpuUserPercent:gt(d?.user),cpuSystemPercent:gt(d?.system),cpuIowaitPercent:gt(d?.iowait),memoryUsedPercent:gt(s.memory?.["memused-percent"]),memoryUsedBytes:Hr(s.memory?.memused),memoryAvailableBytes:Hr(s.memory?.avail),swapUsedPercent:gt(s.memory?.["swpused-percent"]),swapUsedBytes:Hr(s.memory?.swpused)})}return o.sort((s,c)=>s.timestamp.localeCompare(c.timestamp))}function Qu(r){return Object.fromEntries(Object.entries(r.time_series??{}).map(([e,t])=>[e,(t.values??[]).map(([n,i])=>({timestamp:new Date(Number(n)*1000).toISOString(),value:gt(i,Number.NaN)})).filter((n)=>Number.isFinite(n.value))]))}function ha(r){return r.length?r.reduce((e,t)=>e+t,0)/r.length:null}function Jr(r){return r.length?Math.max(...r):null}function Xu(r){return r.length?Math.min(...r):null}async function ya(r){let[e,t]=await Promise.all([r.client.getServerMetrics(r.serverId,{types:["cpu","disk","network"],start:r.from,end:r.to,step:r.step}),Yr(r.remote.host,"LC_ALL=C sadf -j -- -u -r -S",r.remote).catch(()=>"")]),n=Zu(t,r.from,r.to),i=Qu(e),s=(i.cpu??[]).map((m)=>Math.max(0,Math.min(100,m.value/Math.max(1,r.cores)))),c=n.map((m)=>m.cpuUsedPercent),l=s.length?s:c,d=n.map((m)=>m.memoryUsedPercent),u=n.map((m)=>m.swapUsedPercent);return{from:r.from.toISOString(),to:r.to.toISOString(),cores:r.cores,host:n,provider:i,summary:{cpuAveragePercent:ha(l),cpuPeakPercent:Jr(l),memoryAveragePercent:ha(d),memoryPeakPercent:Jr(d),memoryMinimumAvailableBytes:Xu(n.map((m)=>m.memoryAvailableBytes)),swapPeakPercent:Jr(u)}}}function em(r){if(r.length===0)throw Error("A server name cannot be empty.");if(r.length>253)throw Error(`'${r}' is longer than the 253 characters a hostname allows.`);for(let e of r.split(".")){if(e.length===0)throw Error(`'${r}' has an empty label — a hostname cannot contain '..'.`);if(e.length>63)throw Error(`'${e}' is longer than the 63 characters a hostname label allows.`);if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(e))throw Error(`'${e}' is not a valid hostname label. Use letters, digits and hyphens, not starting or ending with a hyphen.`)}}async function va(r,e,t){if(em(e),r===e)throw Error(`'${r}' is already named that.`);if((await t.takenNames()).some((o)=>o===e&&o!==r))throw Error(`'${e}' is already taken. Server names have to be unique within a provider project.`);let i=[];if(t.providerName&&t.renameProvider){let{providerName:o,renameProvider:s}=t;i.push({id:"provider",title:"Rename the server at the provider",change:{from:r,to:e},satisfied:async()=>await o()===e,apply:()=>s(e)})}if(t.stateName&&t.writeStateName){let{stateName:o,writeStateName:s}=t;i.push({id:"state-pin",title:"Update the recorded name in the local driver state",change:{from:r,to:e},satisfied:async()=>{let c=await o();return c===void 0||c===e},apply:()=>s(e)})}if(t.remoteHostname&&t.setRemoteHostname){let{remoteHostname:o,setRemoteHostname:s}=t;i.push({id:"hostname",title:"Set the hostname on the box",change:{from:r,to:e},satisfied:async()=>await o()===e,apply:()=>s(e)})}return i.push({id:"inventory",title:"Rename the fleet inventory record",change:{from:r,to:e},satisfied:async()=>t.inventoryName()===e,apply:async()=>{await t.renameInventory(e)}}),{operation:"server:rename",target:r,steps:i}}function ba(r){let e=`'${r.replace(/'/g,`'"'"'`)}'`;return["set -eu",'TS_CLOUD_OLD="$(hostname)"',`hostnamectl set-hostname ${e} 2>/dev/null || { echo ${e} > /etc/hostname && hostname ${e}; }`,'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${r}/" /etc/hosts)"`,` printf '%s\\n' "$TS_CLOUD_HOSTS" > /etc/hosts`,"else",` printf '127.0.1.1\\t%s\\n' ${e} >> /etc/hosts`,"fi",'printf "%s -> %s\\n" "$TS_CLOUD_OLD" "$(hostname)"'].join(`
|
|
318
|
-
`)}async function tm(){let r=await P(),e=q(process.cwd(),r),t=new et(e.store),n=new Na(t,[new qn("aws"),new qn("hetzner"),new qn("ssh")]);return{controlPlane:e,store:t,service:n}}async function Ve(r){let e=await tm();try{return await r(e)}finally{e.controlPlane.store.close()}}var yt=(r,e)=>{let t=r.store.list(r.controlPlane.project.id).find((n)=>n.id===e||n.name===e);if(!t)throw Error(`Server ${e} was not found.`);return t},fe=(r)=>{f(r instanceof Error?r.message:String(r)),process.exitCode=1};function ei(r,e){let t=Number.parseInt(r??"",10);return Number.isFinite(t)&&t>=0?t:e}function nm(r="3h"){let e=r.match(/^(\d+)(m|h)$/);if(!e)throw Error("--range must use minutes or hours, for example 30m or 3h.");let t=Number(e[1])*(e[2]==="h"?3600000:60000);if(t<300000||t>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return t}function dn(r,e="%"){return r==null?"unavailable":`${r.toFixed(1)}${e}`}async function rm(r,e){let t=await P();if(t.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let n=e.env??process.env.CLOUD_ENV??"production",i=we(t,n),o=await Rt(i);if(!o?.serverId)throw Error(`No pinned Hetzner server was found for ${i}.`);if(![o.serverName,String(o.serverId),o.stackName].includes(r))throw Error(`Refusing to read ${r}: project state is pinned to ${o.serverName}.`);let s=un(t),c=new Vt({apiToken:Wt(s.apiToken,t)}),l=await c.getServer(o.serverId),d=o.publicIp??l.public_net.ipv4?.ip;if(!d)throw Error(`Server ${l.name} has no public IPv4 address.`);let u=new Date,m=new Date(u.getTime()-nm(e.range)),p=Math.min(3600,Math.max(60,ei(e.step,60))),y=await ya({client:c,serverId:l.id,cores:Math.max(1,Number(l.server_type.cores)||1),from:m,to:u,step:p,remote:{host:d,user:o.sshUser??s.sshUser,identityFile:s.sshPrivateKeyPath,connectTimeoutSec:15}});if(e.json){console.log(JSON.stringify({schemaVersion:1,server:l.name,result:y},null,2));return}x(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[l.name,`${y.from} to ${y.to}`,`${dn(y.summary.cpuAveragePercent)} / ${dn(y.summary.cpuPeakPercent)}`,`${dn(y.summary.memoryAveragePercent)} / ${dn(y.summary.memoryPeakPercent)}`,y.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(y.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,dn(y.summary.swapPeakPercent)]])}function Oa(r){let e=r.targetType.prices?.find((t)=>t.location===r.location);return{serverId:r.serverId,serverName:r.serverName,location:r.location,from:r.currentType.name,to:r.targetType.name,capacityAvailable:r.capacityAvailable,alreadyComplete:r.alreadyComplete,upgradeDisk:r.upgradeDisk,target:{cores:r.targetType.cores,memoryGb:r.targetType.memory,diskGb:r.targetType.disk,architecture:r.targetType.architecture,cpuType:r.targetType.cpu_type},price:e?{hourlyNet:e.price_hourly.net,hourlyGross:e.price_hourly.gross,monthlyNet:e.price_monthly.net,monthlyGross:e.price_monthly.gross}:void 0}}function im(r){let e=Oa(r);x(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${e.serverName} (${e.serverId})`,e.location,`${e.from} -> ${e.to}`,e.capacityAvailable?"available":"waiting",`${e.target.cores??0} / ${e.target.memoryGb??0} GB / ${e.target.diskGb??0} GB`,e.price?.monthlyGross??e.price?.monthlyNet??"not reported"]])}async function om(r,e,t){let n=await P();if(n.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let i=t.env??process.env.CLOUD_ENV??"production",o=we(n,i),s=await Rt(o),c=un(n),l=new Vt({apiToken:Wt(c.apiToken,n)}),u=s&&(r===s.serverName||r===String(s.serverId)||r===s.stackName)?await l.getServer(s.serverId):(await l.listServers()).find((E)=>E.name===r||String(E.id)===r);if(!u)throw Error(`Hetzner server ${r} was not found.`);if(s?.serverId&&s.serverId!==u.id)throw Error(`Refusing to resize ${r}: project state is pinned to server ${s.serverId}.`);let m=Sa(e),p=t.upgradeDisk!==!1,y=await Qr(l,u.id,m,p);if(t.json)console.log(JSON.stringify({schemaVersion:1,plan:Oa(y)},null,2));else im(y);if(!t.apply){if(!t.json)a(`Preview only. Re-run with --apply --confirm ${u.name} to execute.`);return}if(t.confirm!==u.name)throw Error(`Resize requires --confirm ${u.name}.`);let w=s?.publicIp??u.public_net.ipv4?.ip;if(!w)throw Error(`Server ${u.name} has no public IPv4 address for verification.`);let g={host:w,user:s?.sshUser??c.sshUser,identityFile:c.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},b=await Da(o),I=new Date().toISOString(),v={schemaVersion:1,operationId:b?.targetType===m&&b.serverId===u.id?b.operationId:crypto.randomUUID(),stackName:o,serverId:u.id,serverName:u.name,sourceType:y.currentType.name,targetType:m,upgradeDisk:p,phase:"planning",status:"running",attempts:b?.targetType===m?b.attempts:0,startedAt:b?.targetType===m?b.startedAt:I,updatedAt:I,manifest:b?.targetType===m?b.manifest:void 0};await ht(v);let C=ei(t.pollSeconds,900)*1000,k=ei(t.maxWaitMinutes,0)*60000,T=Date.now();for(;;){let E=await Qr(l,u.id,m,p);if(!E.capacityAvailable&&!E.alreadyComplete){if(v={...v,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await ht(v),!t.wait){if(!t.json)a(`${m} has no capacity in ${E.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(k>0&&Date.now()-T>=k)throw Error(`Timed out waiting for ${m} capacity in ${E.location}.`);if(!t.json)a(`Waiting ${Math.round(C/1000)} seconds for ${m} capacity...`);await Bun.sleep(C);continue}let D=await Ta(o);try{let N=await(async()=>{try{return v={...v,status:"running",attempts:v.attempts+1,updatedAt:new Date().toISOString()},await ht(v),await $a({client:l,serverId:u.id,targetType:m,upgradeDisk:p,resumeFromOff:v.phase==="shutting-down"||v.phase==="resizing"||v.phase==="powering-on"||v.phase==="verifying",manifest:v.manifest,hooks:{preflight:async()=>{let _=await Aa(g);return v={...v,manifest:_,updatedAt:new Date().toISOString()},await ht(v),_},afterBoot:async(_,B,V,K)=>ka(g,B,V,K),onPhase:async(_,B)=>{if(v={...v,phase:_,status:_==="waiting-capacity"?"waiting-capacity":_==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await ht(v),!t.json)a(`${_}${B?` ${JSON.stringify(B)}`:""}`)}}})}finally{await D()}})();if(v={...v,status:N.status==="completed"||N.status==="already-complete"?"completed":N.status==="recovered"?"recovered":"waiting-capacity",lastError:N.status==="recovered"?N.error:void 0,updatedAt:new Date().toISOString()},await ht(v),t.json)console.log(JSON.stringify({schemaVersion:1,result:N},null,2));else if(N.status==="completed"||N.status==="already-complete")h(`${u.name} is on ${m} and passed full post-boot verification.`);else if(N.status==="recovered"&&N.retryable&&t.wait){a(`Capacity race recovered safely. Waiting ${Math.round(C/1000)} seconds before retry.`),await Bun.sleep(C);continue}else if(N.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${N.error}`);return}catch(N){throw v={...v,status:"failed",lastError:N instanceof Error?N.message:String(N),updatedAt:new Date().toISOString()},await ht(v),N}}}async function sm(r,e){let t=await P();if(t.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let n=e.env??process.env.CLOUD_ENV??"production",i=we(t,n),o=await Rt(i);if(!o?.serverId)throw Error(`No pinned Hetzner server was found for ${i}.`);if(![o.serverName,String(o.serverId),o.stackName].includes(r))throw Error(`Refusing to optimize ${r}: project state is pinned to ${o.serverName}.`);let s=un(t),c=new Vt({apiToken:Wt(s.apiToken,t)}),l=await c.getServer(o.serverId),d=o.publicIp??l.public_net.ipv4?.ip;if(!d)throw Error(`Server ${l.name} has no public IPv4 address.`);let u=Ia(t);if(e.json)console.log(JSON.stringify({schemaVersion:1,server:l.name,plan:u},null,2));else x(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[l.name,u.firewallPorts.join(","),u.monitoring?"on":"off",u.autoUpdates?"on":"off",`${u.swapGb} GB`,"disabled"]]);if(!e.apply){if(!e.json)a(`Preview only. Re-run with --apply --confirm ${l.name} to execute.`);return}if(e.confirm!==l.name)throw Error(`Optimization requires --confirm ${l.name}.`);let m={host:d,user:o.sshUser??s.sshUser,identityFile:s.sshPrivateKeyPath,connectTimeoutSec:15},p=await Xr(m),y=p.routeProbes.filter((V)=>!V.ok),w=t.infrastructure?.compute,g=Zr(w)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,b=p.failedUnits.filter((V)=>!g.has(V));if(b.length>0)throw Error(`Preflight found failed services: ${b.join(", ")}`);if(y.length>0)throw Error(`Preflight found unhealthy routes: ${y.map((V)=>V.domain).join(", ")}`);let I=Zr(w)?[]:Object.values(t.sites??{}).flatMap((V)=>typeof V?.port==="number"&&![80,443].includes(V.port)?[V.port]:[]),v=wa({allowSsh:w?.allowSsh!==!1,sitePorts:I,allowedPorts:w?.firewall?.allowedPorts}),C=(o.firewallId?(await c.listFirewalls()).find((V)=>V.id===o.firewallId):void 0)??(await c.listFirewalls()).find((V)=>V.name===`${t.project.slug}-${n}-app-fw`);if(!C)throw Error(`Managed firewall for ${l.name} was not found.`);let k=await c.setFirewallRules(C.id,v);await Promise.all(k.map((V)=>c.waitForAction(V.id))),await Pa(t,m);let[T,E]=await Promise.all([Xr(m),xa(m)]),D=Ea(u,E),N=Ra(p,T),_=T.routeProbes.filter((V)=>!V.ok);if(N.stoppedServices.length>0)D.push(`services stopped: ${N.stoppedServices.join(", ")}`);if(N.changedRouteFragments.length>0)D.push(`route fragments changed: ${N.changedRouteFragments.join(", ")}`);if(N.missingRouteIds.length>0)D.push(`routes disappeared: ${N.missingRouteIds.join(", ")}`);if(N.changedReleaseLinks.length>0)D.push(`release links changed: ${N.changedReleaseLinks.join(", ")}`);if(N.missingData.length>0)D.push(`databases or volumes disappeared: ${N.missingData.join(", ")}`);if(_.length>0)D.push(`unhealthy routes: ${_.map((V)=>V.domain).join(", ")}`);if(D.length>0)throw Error(`Host optimization verification failed: ${D.join("; ")}`);let B={serverId:l.id,serverName:l.name,services:T.runningServices.length,routes:T.routeIds.length,healthyDomains:T.routeProbes.length,releaseLinks:T.releaseLinks.length,databasesAndVolumes:T.dataCatalog.length,report:E};if(e.json)console.log(JSON.stringify({schemaVersion:1,result:B},null,2));else h(`${l.name} passed full host, rpx route, service, release, and data verification.`)}async function am(r,e,t){let n=await P(),i=t.env??"production",o=we(n,i);await Ve(async(s)=>{let c=yt(s,r),l=s.store.list(s.controlPlane.project.id,!0),d=c.provider==="hetzner"&&c.providerId?(()=>{try{let C=un(n);return new Vt({apiToken:Wt(C.apiToken,n)})}catch{return null}})():null,u=c.providerId?Number(c.providerId):Number.NaN,m=await Rt(o),p=m!=null&&m.serverId===u,y=new zn,w=c.trustState==="pinned",g={takenNames:async()=>{let C=l.map((k)=>k.name);if(d)C.push(...(await d.listServers()).map((k)=>k.name));return C},inventoryName:()=>s.store.get(c.id)?.name??c.name,renameInventory:(C)=>{s.store.update(c.id,{name:C})},...d&&Number.isFinite(u)?{providerName:async()=>(await d.getServer(u)).name,renameProvider:async(C)=>{await d.renameServer(u,C)}}:{},...p?{stateName:async()=>(await Rt(o))?.serverName,writeStateName:async(C)=>{let k=await Rt(o);if(k)await Ca(o,{...k,serverName:C})}}:{},...w?{remoteHostname:async()=>{let C=await y.exec(c,"hostname");return C.code===0?C.stdout.trim():void 0},setRemoteHostname:async(C)=>{let k=await y.exec(c,ba(C));if(k.code!==0)throw Error(k.stderr.trim()||`hostname exited ${k.code}`)}}:{}},b=await va(c.name,e,g),I=await Fn(b);if(!t.apply){let C=[d?"":"provider record (no provider id or no API token)",p?"":"local state pin (none points at this server)",w?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(t.json){console.log(JSON.stringify({schemaVersion:1,operation:b.operation,target:b.target,rename:{from:c.name,to:e},notCovered:C,steps:I.map((k)=>({id:k.step.id,title:k.step.title,state:k.state,change:k.step.change,reason:k.reason}))},null,2));return}for(let k of Mn(b,I))console.log(k);for(let k of C)console.log(` not covered: ${k}`);console.log(" Re-run with --apply to perform it.");return}let v=await Bn(b,I,{log:(C)=>a(C),audit:(C)=>s.controlPlane.store.appendEvent({projectId:s.controlPlane.project.id,resourceId:c.resourceId,type:`${C.operation}.${C.step}.${C.state}`,level:C.state==="failed"?"error":"info",payload:{target:C.target,renameTo:e,...C.error?{error:C.error}:{}}})});if(t.json)console.log(JSON.stringify({schemaVersion:1,outcome:v},null,2));if(!v.success){let C=v.steps.find((k)=>k.state==="failed");throw Error(`${b.operation} stopped at '${C?.title}': ${C?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!t.json)h(`Renamed ${c.name} to ${e}.`)})}function ti(r){r.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(e,t)=>{try{await Ve(async(n)=>{let i=e?[yt(n,e)]:n.store.list(n.controlPlane.project.id),o=i.flatMap((s)=>Object.entries(s.capabilities).map(([c,l])=>({server:s.name,provider:s.provider,action:c,...l})));if(t.json)console.log(JSON.stringify({schemaVersion:1,targets:o},null,2));else x(["Server","Provider","Action","Support","Explanation"],o.map((s)=>[s.server,s.provider,s.action,s.supported?"supported":"unsupported",s.reason??"—"]))})}catch(n){fe(n)}}),r.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(e,t,n)=>{try{await om(e,t,n)}catch(i){fe(i)}}),r.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(e,t)=>{try{await sm(e,t)}catch(n){fe(n)}}),r.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(e,t)=>{try{await rm(e,t)}catch(n){fe(n)}}),r.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(e)=>{try{await Ve(async(t)=>{let n=t.store.list(t.controlPlane.project.id);if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],n.map((i)=>[i.name,i.providerId??"—",`${i.provider} / ${i.region??"external"}`,`${i.status} / ${i.trustState}`,i.roles.join(","),`${i.capacity.cpu??0} / ${i.capacity.memoryBytes??0}`,i.heartbeatAt??"never"]))})}catch(t){fe(t)}}),r.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(e,t)=>{try{await Ve(async(n)=>{let i=t.provider;if(!["aws","hetzner","ssh"].includes(i)||!t.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let o=n.service.enroll({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,provider:i,providerId:t.providerId,endpoint:t.endpoint,sshUser:t.user??"deploy",credentialRef:t.credentialRef??"secret://fleet/agent",region:t.region,roles:String(t.roles??"application").split(","),labels:Object.fromEntries(String(t.labels??"").split(",").map((s)=>s.split("=")).filter((s)=>s[0]&&s[1]))});h(`Enrolled ${o.name} as ${o.id}; no remote mutation was performed.`)})}catch(n){fe(n)}}),r.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(e,t)=>{try{await Ve(async(n)=>{let i=yt(n,e);if(i=await n.service.test(i.id),i.trustState==="rotation_pending"){if(!t.acceptHostKey)throw Error(`Host key changed to ${i.pendingHostKey}; review it first.`);i=n.service.reviewHostKey(i.id,t.acceptHostKey)}let o=await n.service.validate(i.id);if(t.json)console.log(JSON.stringify(o.validation,null,2));else x(["Severity","Code","Finding","Remediation"],(o.validation?.findings??[]).map((s)=>[s.severity,s.code,s.message,s.remediation??"—"]));if(!o.validation?.valid)process.exitCode=1})}catch(n){fe(n)}}),r.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(e,t)=>{try{await Ve(async(n)=>{let i=n.service.bootstrap(yt(n,e).id,!!t.apply);if(i.preview)x(["Step"],i.steps.map((o)=>[o]));else h(`Bootstrap queued: ${i.operation?.id}`)})}catch(n){fe(n)}}),r.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(e,t,n)=>{try{await am(e,t,n)}catch(i){fe(i)}}),r.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(e,t)=>{try{await Ve(async(n)=>h(n.service.drain(yt(n,e).id,!!t.complete).status))}catch(n){fe(n)}}),r.command("server:uncordon <name>","Return a server to scheduling").action(async(e)=>{try{await Ve(async(t)=>{t.service.uncordon(yt(t,e).id),h(`Uncordoned ${e}.`)})}catch(t){fe(t)}}),r.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(e,t)=>{try{await Ve(async(n)=>{n.service.archive(yt(n,e).id,t.confirm??""),h(`Archived ${e}; provider infrastructure was not terminated.`)})}catch(n){fe(n)}}),r.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(e)=>{try{await Ve(async(t)=>{let n=yt(t,e);if(n.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let i=Bun.spawn(["ssh","-p",String(n.sshPort),"-o","StrictHostKeyChecking=yes",`${n.sshUser}@${n.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),o=await i.exited;if(o)process.exitCode=o})}catch(t){fe(t)}});for(let[e,t]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"]])r.command(e,t).action(async(...n)=>be(e.split(" ")[0],{target:String(n[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}async function cm(){let r=await P(),e=q(process.cwd(),r),t=new ja(e.store),n=new Fa(t,new et(e.store));return{controlPlane:e,store:t,service:n}}async function mn(r){let e=await cm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}var Gn=(r)=>Object.fromEntries(String(r??"").split(",").map((e)=>e.split("=")).filter((e)=>e[0]&&e[1])),La=(r)=>Object.fromEntries(Object.entries(Gn(r)).map(([e,t])=>[e,Number(t)]));function ni(r){r.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(e)=>mn((t)=>{let n=t.store.listPools(t.controlPlane.project.id);if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],n.map((i)=>[i.name,i.purpose,i.backend,`${i.region??"any"} / ${i.architecture??"any"}`,i.status,JSON.stringify(i.capacity),String(i.concurrency)]))})),r.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(e,t)=>mn((n)=>{let{purpose:i,backend:o}=t;if(!["application","build","worker","monitoring","backup"].includes(i)||!["server","ecs","asg"].includes(o))throw Error("Unsupported pool purpose or backend.");let s=n.store.createPool({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,purpose:i,backend:o,region:t.region,architecture:t.arch,labels:Gn(t.labels),requiredServerLabels:Gn(t.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...La(t.capacity)},maxWorkloads:Number(t.max),costWeight:1,concurrency:Number(t.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});h(`Created ${s.name} (${s.id}).`)})),r.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(e,t)=>mn((n)=>{let i=n.store.listPools(n.controlPlane.project.id).find((s)=>s.id===e||s.name===e),o=new et(n.controlPlane.store).list(n.controlPlane.project.id).find((s)=>s.id===t||s.name===t);if(!i||!o)throw Error("Pool or server was not found.");n.store.addMember(i.id,o.id),h(`Attached ${o.name} to ${i.name}.`)})),r.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(e)=>mn((t)=>{let n=t.service.explain(t.controlPlane.project.id,{purpose:e.purpose,resources:La(e.resources),region:e.region,architecture:e.arch,labels:Gn(e.labels)});if(e.json)console.log(JSON.stringify(n,null,2));else x(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],n.map((i)=>[i.poolName,i.serverId??"provider-managed",i.eligible?"yes":"no",JSON.stringify(i.available),`${i.score.fit.toFixed(2)} / ${i.score.spread} / ${i.score.cost}`,i.reasons.join("; ")||"eligible"]))})),r.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(e)=>mn((t)=>{let n=t.store.listPools(t.controlPlane.project.id).find((o)=>o.id===e||o.name===e);if(!n)throw Error("Pool was not found.");let i=t.service.drainPool(n.id);h(`Draining ${n.name}: moved ${i.moved.length}, blocked ${i.blocked.length} stateful placement(s).`)}))}async function lm(){let r=await P(),e=q(process.cwd(),r),t=new Ma(e.store),n=new Ba(t);return{controlPlane:e,store:t,service:n}}async function It(r){let e=await lm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}var pn=(r,e)=>{let t=r.store.list(r.controlPlane.project.id).find((n)=>n.id===e||n.name===e);if(!t)throw Error("Regional topology was not found.");return t},dm=(r)=>r.split(",").map((e,t)=>{let[n,i="aws"]=e.split(":");return{region:String(n),provider:i,role:t===0?"primary":"secondary"}}),um=(r)=>{let e=new Set(["s3","dynamodb","secrets"]),t=r.split(",").map((i)=>i.trim()),n=t.find((i)=>!e.has(i));if(n)throw Error(`Unsupported replication kind: ${n}`);return t};function ri(r){r.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(e)=>It((t)=>{let n=t.store.list(t.controlPlane.project.id).map((i)=>({topology:i,targets:t.store.targets(i.id),channels:t.store.channels(i.id),route:t.store.route(i.id),executions:t.store.executions(i.id)}));if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Hostname","Active","Status","Revision","Replication"],n.map((i)=>[i.topology.name,i.topology.hostname,i.topology.activeRegion,i.topology.status,i.topology.revision??"—",`${i.channels.filter((o)=>o.status==="in_sync").length}/${i.channels.length} in sync`]))})),r.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(e,t)=>It((n)=>{if(!t.hostname||!t.regions)throw Error("--hostname and --regions are required.");let i=n.service.create({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,hostname:t.hostname,regions:dm(t.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:um(String(t.replicate)),maxLagSeconds:Number(t.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!t.cdn,wafEnabled:!!t.waf});h(`Created ${i.name} (${i.id}); run region:rollout with an immutable manifest.`)})),r.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(e,t,n)=>It((i)=>x(["Step"],i.service.plan(pn(i,e).id,t,n.target).map((o)=>[o])))),r.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(e,t,n)=>It(async(i)=>{let o=n.manifest?await Bun.file(n.manifest).json():{},s=i.service.enqueue({topologyId:pn(i,e).id,kind:"rollout",revision:t,manifest:o});h(`Regional rollout queued: ${s.operation.id}`)})),r.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"failover",targetRegion:t});h(`Failover queued: ${i.operation.id}`)})),r.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"failback",targetRegion:t});h(`Failback queued: ${i.operation.id}`)})),r.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"destroy",confirmation:t.confirm});h(`Regional teardown queued: ${i.operation.id}; replicated data remains retained.`)}))}var fn="0.12.4";async function pm(){let r=await P(),e=q(process.cwd(),r),t=new _a(e.store),n=new za(t),i=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((o)=>new Ua(o,e.store,e.project.id,e.organization.id));return{controlPlane:e,store:t,service:n,cleanup:i}}async function tt(r){let e=await pm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}function ii(r){r.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(e)=>tt((t)=>{let n={manifests:t.store.manifests(t.controlPlane.organization.id),windows:t.store.windows(t.controlPlane.project.id),campaigns:t.store.campaigns(t.controlPlane.project.id),cleanups:t.store.cleanups(t.controlPlane.project.id),drills:t.store.drills(t.controlPlane.project.id)},i=[...n.manifests.map((o)=>["update",o.version,o.compatibility.compatible?"compatible":"blocked",o.compatibility.reasons.join("; ")||o.channel]),...n.campaigns.map((o)=>["upgrade",o.id,o.status,o.currentStage??o.fromVersion]),...n.cleanups.map((o)=>["cleanup",o.kind,o.status,`${o.candidates.length} items / ${o.estimatedBytes} bytes`]),...n.drills.map((o)=>["DR drill",o.scenario,o.status,o.isolatedTarget])];if(e.json)console.log(JSON.stringify(n,null,2));else x(["Area","Name / version","Status","Detail"],i)})),r.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(e,t)=>tt(async(n)=>{let i=n.store.addTrustedKey({organizationId:n.controlPlane.organization.id,name:e,publicKeyPem:await Bun.file(t).text()});h(`Trusted ${i.name}: ${i.fingerprint}`)})),r.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(e,t,n)=>tt(async(i)=>{let o=await Bun.file(e).json(),s=(await Bun.file(t).text()).trim(),c=i.store.importManifest({organizationId:i.controlPlane.organization.id,keyId:n,document:o,signature:s,current:{schemaVersion:i.controlPlane.store.health().schemaVersion,currentVersion:fn,platform:process.platform,architecture:process.arch}});h(`Verified ${c.version}; ${c.compatibility.compatible?"compatible":"blocked: "+c.compatibility.reasons.join("; ")}`)})),r.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(e,t,n)=>tt((i)=>{let o=i.store.createWindow({projectId:i.controlPlane.project.id,name:e,schedule:t,timezone:n.timezone,durationMinutes:Number(n.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});h(`Created ${o.name} (${o.id}).`)})),r.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(e,t,n)=>tt((i)=>{let o=new et(i.controlPlane.store).list(i.controlPlane.project.id).filter((l)=>l.status==="ready").map((l)=>({serverId:l.id,target:l.name,previousVersion:l.bootstrapVersion??fn}));if(!o.length)o.push({target:"control-plane",previousVersion:fn});let s=i.store.createCampaign({projectId:i.controlPlane.project.id,manifestId:e,fromVersion:fn,strategy:n.strategy==="rolling"?"rolling":"canary",batchSize:Number(n.batch),healthGate:{kind:"platform"},backupId:t,targets:o}),c=i.service.enqueueCampaign(s.id);h(`Staged upgrade queued: ${c.operation.id}`)})),r.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(e,t)=>tt(async(n)=>{let i=await n.service.previewCleanup({projectId:n.controlPlane.project.id,kind:e,criteria:{olderThanDays:Number(t.olderThan)}},n.cleanup);x(["ID","Candidate","Bytes"],i.candidates.map((o)=>[o.id,o.label,String(o.bytes)])),a(`Apply with: cloud cleanup:apply ${i.id} --confirm "DELETE ${i.candidates.length} ${i.kind}"`)})),r.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(e,t)=>tt((n)=>{let i=n.service.enqueueCleanup(e,String(t.confirm??""));h(`Cleanup queued: ${i.operation.id}`)})),r.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(e,t,n)=>tt((i)=>{let o=i.store.createDrill({projectId:i.controlPlane.project.id,scenario:e,isolatedTarget:t,expectedRpoMinutes:Number(n.rpo),expectedRtoMinutes:Number(n.rto),recoveryPointId:n.recoveryPoint,topologyId:n.topology});h(`Planned isolated drill ${o.id}.`)})),r.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(e)=>tt((t)=>{let n=t.service.enqueueDrill(e);h(`DR drill queued: ${n.operation.id}`)}))}async function oi(){try{return(await P()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function si(r){r.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(e)=>{S("Lambda Functions");let t=e?.region||await oi(),n=new nt(t);try{let{Functions:i=[]}=await n.listFunctions({MaxItems:50});if(!i.length){a("No functions found");return}x(["Name","Runtime","Memory","Timeout","Last Modified"],i.map((o)=>[o.FunctionName??"-",o.Runtime??"-",o.MemorySize?`${o.MemorySize} MB`:"-",o.Timeout?`${o.Timeout}s`:"-",o.LastModified??"-"]))}catch(i){f(`Failed to list functions: ${i.message}`),process.exitCode=1}}),r.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(e,t)=>{S(`Invoking ${e}`);let n=t?.region||await oi(),i=new nt(n),o=new A("Invoking function...");o.start();try{let s=await i.invoke({FunctionName:e,InvocationType:t?.async?"Event":"RequestResponse",Payload:t?.payload||"{}",LogType:t?.async?"None":"Tail"});if(s.FunctionError){if(o.fail(`Function returned an error (${s.FunctionError})`),s.Payload)a(s.Payload);process.exitCode=1;return}if(o.succeed(`Invoked (status ${s.StatusCode})`),s.Payload)a(`
|
|
318
|
+
`)}async function tm(){let r=await P(),e=q(process.cwd(),r),t=new et(e.store),n=new Na(t,[new qn("aws"),new qn("hetzner"),new qn("ssh")]);return{controlPlane:e,store:t,service:n}}async function Ve(r){let e=await tm();try{return await r(e)}finally{e.controlPlane.store.close()}}var yt=(r,e)=>{let t=r.store.list(r.controlPlane.project.id).find((n)=>n.id===e||n.name===e);if(!t)throw Error(`Server ${e} was not found.`);return t},fe=(r)=>{f(r instanceof Error?r.message:String(r)),process.exitCode=1};function ei(r,e){let t=Number.parseInt(r??"",10);return Number.isFinite(t)&&t>=0?t:e}function nm(r="3h"){let e=r.match(/^(\d+)(m|h)$/);if(!e)throw Error("--range must use minutes or hours, for example 30m or 3h.");let t=Number(e[1])*(e[2]==="h"?3600000:60000);if(t<300000||t>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return t}function dn(r,e="%"){return r==null?"unavailable":`${r.toFixed(1)}${e}`}async function rm(r,e){let t=await P();if(t.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let n=e.env??process.env.CLOUD_ENV??"production",i=we(t,n),o=await Rt(i);if(!o?.serverId)throw Error(`No pinned Hetzner server was found for ${i}.`);if(![o.serverName,String(o.serverId),o.stackName].includes(r))throw Error(`Refusing to read ${r}: project state is pinned to ${o.serverName}.`);let s=un(t),c=new Vt({apiToken:Wt(s.apiToken,t)}),l=await c.getServer(o.serverId),d=o.publicIp??l.public_net.ipv4?.ip;if(!d)throw Error(`Server ${l.name} has no public IPv4 address.`);let u=new Date,m=new Date(u.getTime()-nm(e.range)),p=Math.min(3600,Math.max(60,ei(e.step,60))),y=await ya({client:c,serverId:l.id,cores:Math.max(1,Number(l.server_type.cores)||1),from:m,to:u,step:p,remote:{host:d,user:o.sshUser??s.sshUser,identityFile:s.sshPrivateKeyPath,connectTimeoutSec:15}});if(e.json){console.log(JSON.stringify({schemaVersion:1,server:l.name,result:y},null,2));return}x(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[l.name,`${y.from} to ${y.to}`,`${dn(y.summary.cpuAveragePercent)} / ${dn(y.summary.cpuPeakPercent)}`,`${dn(y.summary.memoryAveragePercent)} / ${dn(y.summary.memoryPeakPercent)}`,y.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(y.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,dn(y.summary.swapPeakPercent)]])}function Oa(r){let e=r.targetType.prices?.find((t)=>t.location===r.location);return{serverId:r.serverId,serverName:r.serverName,location:r.location,from:r.currentType.name,to:r.targetType.name,capacityAvailable:r.capacityAvailable,alreadyComplete:r.alreadyComplete,upgradeDisk:r.upgradeDisk,target:{cores:r.targetType.cores,memoryGb:r.targetType.memory,diskGb:r.targetType.disk,architecture:r.targetType.architecture,cpuType:r.targetType.cpu_type},price:e?{hourlyNet:e.price_hourly.net,hourlyGross:e.price_hourly.gross,monthlyNet:e.price_monthly.net,monthlyGross:e.price_monthly.gross}:void 0}}function im(r){let e=Oa(r);x(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${e.serverName} (${e.serverId})`,e.location,`${e.from} -> ${e.to}`,e.capacityAvailable?"available":"waiting",`${e.target.cores??0} / ${e.target.memoryGb??0} GB / ${e.target.diskGb??0} GB`,e.price?.monthlyGross??e.price?.monthlyNet??"not reported"]])}async function om(r,e,t){let n=await P();if(n.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let i=t.env??process.env.CLOUD_ENV??"production",o=we(n,i),s=await Rt(o),c=un(n),l=new Vt({apiToken:Wt(c.apiToken,n)}),u=s&&(r===s.serverName||r===String(s.serverId)||r===s.stackName)?await l.getServer(s.serverId):(await l.listServers()).find((E)=>E.name===r||String(E.id)===r);if(!u)throw Error(`Hetzner server ${r} was not found.`);if(s?.serverId&&s.serverId!==u.id)throw Error(`Refusing to resize ${r}: project state is pinned to server ${s.serverId}.`);let m=Sa(e),p=t.upgradeDisk!==!1,y=await Qr(l,u.id,m,p);if(t.json)console.log(JSON.stringify({schemaVersion:1,plan:Oa(y)},null,2));else im(y);if(!t.apply){if(!t.json)a(`Preview only. Re-run with --apply --confirm ${u.name} to execute.`);return}if(t.confirm!==u.name)throw Error(`Resize requires --confirm ${u.name}.`);let w=s?.publicIp??u.public_net.ipv4?.ip;if(!w)throw Error(`Server ${u.name} has no public IPv4 address for verification.`);let g={host:w,user:s?.sshUser??c.sshUser,identityFile:c.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},b=await Da(o),I=new Date().toISOString(),v={schemaVersion:1,operationId:b?.targetType===m&&b.serverId===u.id?b.operationId:crypto.randomUUID(),stackName:o,serverId:u.id,serverName:u.name,sourceType:y.currentType.name,targetType:m,upgradeDisk:p,phase:"planning",status:"running",attempts:b?.targetType===m?b.attempts:0,startedAt:b?.targetType===m?b.startedAt:I,updatedAt:I,manifest:b?.targetType===m?b.manifest:void 0};await ht(v);let C=ei(t.pollSeconds,900)*1000,k=ei(t.maxWaitMinutes,0)*60000,T=Date.now();for(;;){let E=await Qr(l,u.id,m,p);if(!E.capacityAvailable&&!E.alreadyComplete){if(v={...v,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await ht(v),!t.wait){if(!t.json)a(`${m} has no capacity in ${E.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(k>0&&Date.now()-T>=k)throw Error(`Timed out waiting for ${m} capacity in ${E.location}.`);if(!t.json)a(`Waiting ${Math.round(C/1000)} seconds for ${m} capacity...`);await Bun.sleep(C);continue}let D=await Ta(o);try{let N=await(async()=>{try{return v={...v,status:"running",attempts:v.attempts+1,updatedAt:new Date().toISOString()},await ht(v),await $a({client:l,serverId:u.id,targetType:m,upgradeDisk:p,resumeFromOff:v.phase==="shutting-down"||v.phase==="resizing"||v.phase==="powering-on"||v.phase==="verifying",manifest:v.manifest,hooks:{preflight:async()=>{let _=await Aa(g);return v={...v,manifest:_,updatedAt:new Date().toISOString()},await ht(v),_},afterBoot:async(_,B,V,K)=>ka(g,B,V,K),onPhase:async(_,B)=>{if(v={...v,phase:_,status:_==="waiting-capacity"?"waiting-capacity":_==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await ht(v),!t.json)a(`${_}${B?` ${JSON.stringify(B)}`:""}`)}}})}finally{await D()}})();if(v={...v,status:N.status==="completed"||N.status==="already-complete"?"completed":N.status==="recovered"?"recovered":"waiting-capacity",lastError:N.status==="recovered"?N.error:void 0,updatedAt:new Date().toISOString()},await ht(v),t.json)console.log(JSON.stringify({schemaVersion:1,result:N},null,2));else if(N.status==="completed"||N.status==="already-complete")h(`${u.name} is on ${m} and passed full post-boot verification.`);else if(N.status==="recovered"&&N.retryable&&t.wait){a(`Capacity race recovered safely. Waiting ${Math.round(C/1000)} seconds before retry.`),await Bun.sleep(C);continue}else if(N.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${N.error}`);return}catch(N){throw v={...v,status:"failed",lastError:N instanceof Error?N.message:String(N),updatedAt:new Date().toISOString()},await ht(v),N}}}async function sm(r,e){let t=await P();if(t.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let n=e.env??process.env.CLOUD_ENV??"production",i=we(t,n),o=await Rt(i);if(!o?.serverId)throw Error(`No pinned Hetzner server was found for ${i}.`);if(![o.serverName,String(o.serverId),o.stackName].includes(r))throw Error(`Refusing to optimize ${r}: project state is pinned to ${o.serverName}.`);let s=un(t),c=new Vt({apiToken:Wt(s.apiToken,t)}),l=await c.getServer(o.serverId),d=o.publicIp??l.public_net.ipv4?.ip;if(!d)throw Error(`Server ${l.name} has no public IPv4 address.`);let u=Ia(t);if(e.json)console.log(JSON.stringify({schemaVersion:1,server:l.name,plan:u},null,2));else x(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[l.name,u.firewallPorts.join(","),u.monitoring?"on":"off",u.autoUpdates?"on":"off",`${u.swapGb} GB`,"disabled"]]);if(!e.apply){if(!e.json)a(`Preview only. Re-run with --apply --confirm ${l.name} to execute.`);return}if(e.confirm!==l.name)throw Error(`Optimization requires --confirm ${l.name}.`);let m={host:d,user:o.sshUser??s.sshUser,identityFile:s.sshPrivateKeyPath,connectTimeoutSec:15},p=await Xr(m),y=p.routeProbes.filter((V)=>!V.ok),w=t.infrastructure?.compute,g=Zr(w)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,b=p.failedUnits.filter((V)=>!g.has(V));if(b.length>0)throw Error(`Preflight found failed services: ${b.join(", ")}`);if(y.length>0)throw Error(`Preflight found unhealthy routes: ${y.map((V)=>V.domain).join(", ")}`);let I=Zr(w)?[]:Object.values(t.sites??{}).flatMap((V)=>typeof V?.port==="number"&&![80,443].includes(V.port)?[V.port]:[]),v=wa({allowSsh:w?.allowSsh!==!1,sitePorts:I,allowedPorts:w?.firewall?.allowedPorts}),C=(o.firewallId?(await c.listFirewalls()).find((V)=>V.id===o.firewallId):void 0)??(await c.listFirewalls()).find((V)=>V.name===`${t.project.slug}-${n}-app-fw`);if(!C)throw Error(`Managed firewall for ${l.name} was not found.`);let k=await c.setFirewallRules(C.id,v);await Promise.all(k.map((V)=>c.waitForAction(V.id))),await Pa(t,m);let[T,E]=await Promise.all([Xr(m),xa(m)]),D=Ea(u,E),N=Ra(p,T),_=T.routeProbes.filter((V)=>!V.ok);if(N.stoppedServices.length>0)D.push(`services stopped: ${N.stoppedServices.join(", ")}`);if(N.changedRouteFragments.length>0)D.push(`route fragments changed: ${N.changedRouteFragments.join(", ")}`);if(N.missingRouteIds.length>0)D.push(`routes disappeared: ${N.missingRouteIds.join(", ")}`);if(N.changedReleaseLinks.length>0)D.push(`release links changed: ${N.changedReleaseLinks.join(", ")}`);if(N.missingData.length>0)D.push(`databases or volumes disappeared: ${N.missingData.join(", ")}`);if(_.length>0)D.push(`unhealthy routes: ${_.map((V)=>V.domain).join(", ")}`);if(D.length>0)throw Error(`Host optimization verification failed: ${D.join("; ")}`);let B={serverId:l.id,serverName:l.name,services:T.runningServices.length,routes:T.routeIds.length,healthyDomains:T.routeProbes.length,releaseLinks:T.releaseLinks.length,databasesAndVolumes:T.dataCatalog.length,report:E};if(e.json)console.log(JSON.stringify({schemaVersion:1,result:B},null,2));else h(`${l.name} passed full host, rpx route, service, release, and data verification.`)}async function am(r,e,t){let n=await P(),i=t.env??"production",o=we(n,i);await Ve(async(s)=>{let c=yt(s,r),l=s.store.list(s.controlPlane.project.id,!0),d=c.provider==="hetzner"&&c.providerId?(()=>{try{let C=un(n);return new Vt({apiToken:Wt(C.apiToken,n)})}catch{return null}})():null,u=c.providerId?Number(c.providerId):Number.NaN,m=await Rt(o),p=m!=null&&m.serverId===u,y=new zn,w=c.trustState==="pinned",g={takenNames:async()=>{let C=l.map((k)=>k.name);if(d)C.push(...(await d.listServers()).map((k)=>k.name));return C},inventoryName:()=>s.store.get(c.id)?.name??c.name,renameInventory:(C)=>{s.store.update(c.id,{name:C})},...d&&Number.isFinite(u)?{providerName:async()=>(await d.getServer(u)).name,renameProvider:async(C)=>{await d.renameServer(u,C)}}:{},...p?{stateName:async()=>(await Rt(o))?.serverName,writeStateName:async(C)=>{let k=await Rt(o);if(k)await Ca(o,{...k,serverName:C})}}:{},...w?{remoteHostname:async()=>{let C=await y.exec(c,"hostname");return C.code===0?C.stdout.trim():void 0},setRemoteHostname:async(C)=>{let k=await y.exec(c,ba(C));if(k.code!==0)throw Error(k.stderr.trim()||`hostname exited ${k.code}`)}}:{}},b=await va(c.name,e,g),I=await Fn(b);if(!t.apply){let C=[d?"":"provider record (no provider id or no API token)",p?"":"local state pin (none points at this server)",w?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(t.json){console.log(JSON.stringify({schemaVersion:1,operation:b.operation,target:b.target,rename:{from:c.name,to:e},notCovered:C,steps:I.map((k)=>({id:k.step.id,title:k.step.title,state:k.state,change:k.step.change,reason:k.reason}))},null,2));return}for(let k of Mn(b,I))console.log(k);for(let k of C)console.log(` not covered: ${k}`);console.log(" Re-run with --apply to perform it.");return}let v=await Bn(b,I,{log:(C)=>a(C),audit:(C)=>s.controlPlane.store.appendEvent({projectId:s.controlPlane.project.id,resourceId:c.resourceId,type:`${C.operation}.${C.step}.${C.state}`,level:C.state==="failed"?"error":"info",payload:{target:C.target,renameTo:e,...C.error?{error:C.error}:{}}})});if(t.json)console.log(JSON.stringify({schemaVersion:1,outcome:v},null,2));if(!v.success){let C=v.steps.find((k)=>k.state==="failed");throw Error(`${b.operation} stopped at '${C?.title}': ${C?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!t.json)h(`Renamed ${c.name} to ${e}.`)})}function ti(r){r.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(e,t)=>{try{await Ve(async(n)=>{let i=e?[yt(n,e)]:n.store.list(n.controlPlane.project.id),o=i.flatMap((s)=>Object.entries(s.capabilities).map(([c,l])=>({server:s.name,provider:s.provider,action:c,...l})));if(t.json)console.log(JSON.stringify({schemaVersion:1,targets:o},null,2));else x(["Server","Provider","Action","Support","Explanation"],o.map((s)=>[s.server,s.provider,s.action,s.supported?"supported":"unsupported",s.reason??"—"]))})}catch(n){fe(n)}}),r.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(e,t,n)=>{try{await om(e,t,n)}catch(i){fe(i)}}),r.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(e,t)=>{try{await sm(e,t)}catch(n){fe(n)}}),r.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(e,t)=>{try{await rm(e,t)}catch(n){fe(n)}}),r.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(e)=>{try{await Ve(async(t)=>{let n=t.store.list(t.controlPlane.project.id);if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],n.map((i)=>[i.name,i.providerId??"—",`${i.provider} / ${i.region??"external"}`,`${i.status} / ${i.trustState}`,i.roles.join(","),`${i.capacity.cpu??0} / ${i.capacity.memoryBytes??0}`,i.heartbeatAt??"never"]))})}catch(t){fe(t)}}),r.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(e,t)=>{try{await Ve(async(n)=>{let i=t.provider;if(!["aws","hetzner","ssh"].includes(i)||!t.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let o=n.service.enroll({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,provider:i,providerId:t.providerId,endpoint:t.endpoint,sshUser:t.user??"deploy",credentialRef:t.credentialRef??"secret://fleet/agent",region:t.region,roles:String(t.roles??"application").split(","),labels:Object.fromEntries(String(t.labels??"").split(",").map((s)=>s.split("=")).filter((s)=>s[0]&&s[1]))});h(`Enrolled ${o.name} as ${o.id}; no remote mutation was performed.`)})}catch(n){fe(n)}}),r.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(e,t)=>{try{await Ve(async(n)=>{let i=yt(n,e);if(i=await n.service.test(i.id),i.trustState==="rotation_pending"){if(!t.acceptHostKey)throw Error(`Host key changed to ${i.pendingHostKey}; review it first.`);i=n.service.reviewHostKey(i.id,t.acceptHostKey)}let o=await n.service.validate(i.id);if(t.json)console.log(JSON.stringify(o.validation,null,2));else x(["Severity","Code","Finding","Remediation"],(o.validation?.findings??[]).map((s)=>[s.severity,s.code,s.message,s.remediation??"—"]));if(!o.validation?.valid)process.exitCode=1})}catch(n){fe(n)}}),r.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(e,t)=>{try{await Ve(async(n)=>{let i=n.service.bootstrap(yt(n,e).id,!!t.apply);if(i.preview)x(["Step"],i.steps.map((o)=>[o]));else h(`Bootstrap queued: ${i.operation?.id}`)})}catch(n){fe(n)}}),r.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(e,t,n)=>{try{await am(e,t,n)}catch(i){fe(i)}}),r.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(e,t)=>{try{await Ve(async(n)=>h(n.service.drain(yt(n,e).id,!!t.complete).status))}catch(n){fe(n)}}),r.command("server:uncordon <name>","Return a server to scheduling").action(async(e)=>{try{await Ve(async(t)=>{t.service.uncordon(yt(t,e).id),h(`Uncordoned ${e}.`)})}catch(t){fe(t)}}),r.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(e,t)=>{try{await Ve(async(n)=>{n.service.archive(yt(n,e).id,t.confirm??""),h(`Archived ${e}; provider infrastructure was not terminated.`)})}catch(n){fe(n)}}),r.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(e)=>{try{await Ve(async(t)=>{let n=yt(t,e);if(n.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let i=Bun.spawn(["ssh","-p",String(n.sshPort),"-o","StrictHostKeyChecking=yes",`${n.sshUser}@${n.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),o=await i.exited;if(o)process.exitCode=o})}catch(t){fe(t)}});for(let[e,t]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"]])r.command(e,t).action(async(...n)=>be(e.split(" ")[0],{target:String(n[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}async function cm(){let r=await P(),e=q(process.cwd(),r),t=new ja(e.store),n=new Fa(t,new et(e.store));return{controlPlane:e,store:t,service:n}}async function mn(r){let e=await cm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}var Gn=(r)=>Object.fromEntries(String(r??"").split(",").map((e)=>e.split("=")).filter((e)=>e[0]&&e[1])),La=(r)=>Object.fromEntries(Object.entries(Gn(r)).map(([e,t])=>[e,Number(t)]));function ni(r){r.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(e)=>mn((t)=>{let n=t.store.listPools(t.controlPlane.project.id);if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],n.map((i)=>[i.name,i.purpose,i.backend,`${i.region??"any"} / ${i.architecture??"any"}`,i.status,JSON.stringify(i.capacity),String(i.concurrency)]))})),r.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(e,t)=>mn((n)=>{let{purpose:i,backend:o}=t;if(!["application","build","worker","monitoring","backup"].includes(i)||!["server","ecs","asg"].includes(o))throw Error("Unsupported pool purpose or backend.");let s=n.store.createPool({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,purpose:i,backend:o,region:t.region,architecture:t.arch,labels:Gn(t.labels),requiredServerLabels:Gn(t.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...La(t.capacity)},maxWorkloads:Number(t.max),costWeight:1,concurrency:Number(t.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});h(`Created ${s.name} (${s.id}).`)})),r.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(e,t)=>mn((n)=>{let i=n.store.listPools(n.controlPlane.project.id).find((s)=>s.id===e||s.name===e),o=new et(n.controlPlane.store).list(n.controlPlane.project.id).find((s)=>s.id===t||s.name===t);if(!i||!o)throw Error("Pool or server was not found.");n.store.addMember(i.id,o.id),h(`Attached ${o.name} to ${i.name}.`)})),r.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(e)=>mn((t)=>{let n=t.service.explain(t.controlPlane.project.id,{purpose:e.purpose,resources:La(e.resources),region:e.region,architecture:e.arch,labels:Gn(e.labels)});if(e.json)console.log(JSON.stringify(n,null,2));else x(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],n.map((i)=>[i.poolName,i.serverId??"provider-managed",i.eligible?"yes":"no",JSON.stringify(i.available),`${i.score.fit.toFixed(2)} / ${i.score.spread} / ${i.score.cost}`,i.reasons.join("; ")||"eligible"]))})),r.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(e)=>mn((t)=>{let n=t.store.listPools(t.controlPlane.project.id).find((o)=>o.id===e||o.name===e);if(!n)throw Error("Pool was not found.");let i=t.service.drainPool(n.id);h(`Draining ${n.name}: moved ${i.moved.length}, blocked ${i.blocked.length} stateful placement(s).`)}))}async function lm(){let r=await P(),e=q(process.cwd(),r),t=new Ma(e.store),n=new Ba(t);return{controlPlane:e,store:t,service:n}}async function It(r){let e=await lm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}var pn=(r,e)=>{let t=r.store.list(r.controlPlane.project.id).find((n)=>n.id===e||n.name===e);if(!t)throw Error("Regional topology was not found.");return t},dm=(r)=>r.split(",").map((e,t)=>{let[n,i="aws"]=e.split(":");return{region:String(n),provider:i,role:t===0?"primary":"secondary"}}),um=(r)=>{let e=new Set(["s3","dynamodb","secrets"]),t=r.split(",").map((i)=>i.trim()),n=t.find((i)=>!e.has(i));if(n)throw Error(`Unsupported replication kind: ${n}`);return t};function ri(r){r.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(e)=>It((t)=>{let n=t.store.list(t.controlPlane.project.id).map((i)=>({topology:i,targets:t.store.targets(i.id),channels:t.store.channels(i.id),route:t.store.route(i.id),executions:t.store.executions(i.id)}));if(e.json)console.log(JSON.stringify(n,null,2));else x(["Name","Hostname","Active","Status","Revision","Replication"],n.map((i)=>[i.topology.name,i.topology.hostname,i.topology.activeRegion,i.topology.status,i.topology.revision??"—",`${i.channels.filter((o)=>o.status==="in_sync").length}/${i.channels.length} in sync`]))})),r.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(e,t)=>It((n)=>{if(!t.hostname||!t.regions)throw Error("--hostname and --regions are required.");let i=n.service.create({organizationId:n.controlPlane.organization.id,projectId:n.controlPlane.project.id,name:e,hostname:t.hostname,regions:dm(t.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:um(String(t.replicate)),maxLagSeconds:Number(t.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!t.cdn,wafEnabled:!!t.waf});h(`Created ${i.name} (${i.id}); run region:rollout with an immutable manifest.`)})),r.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(e,t,n)=>It((i)=>x(["Step"],i.service.plan(pn(i,e).id,t,n.target).map((o)=>[o])))),r.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(e,t,n)=>It(async(i)=>{let o=n.manifest?await Bun.file(n.manifest).json():{},s=i.service.enqueue({topologyId:pn(i,e).id,kind:"rollout",revision:t,manifest:o});h(`Regional rollout queued: ${s.operation.id}`)})),r.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"failover",targetRegion:t});h(`Failover queued: ${i.operation.id}`)})),r.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"failback",targetRegion:t});h(`Failback queued: ${i.operation.id}`)})),r.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(e,t)=>It((n)=>{let i=n.service.enqueue({topologyId:pn(n,e).id,kind:"destroy",confirmation:t.confirm});h(`Regional teardown queued: ${i.operation.id}; replicated data remains retained.`)}))}var fn="0.12.6";async function pm(){let r=await P(),e=q(process.cwd(),r),t=new _a(e.store),n=new za(t),i=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((o)=>new Ua(o,e.store,e.project.id,e.organization.id));return{controlPlane:e,store:t,service:n,cleanup:i}}async function tt(r){let e=await pm();try{await r(e)}catch(t){f(t instanceof Error?t.message:String(t)),process.exitCode=1}finally{e.controlPlane.store.close()}}function ii(r){r.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(e)=>tt((t)=>{let n={manifests:t.store.manifests(t.controlPlane.organization.id),windows:t.store.windows(t.controlPlane.project.id),campaigns:t.store.campaigns(t.controlPlane.project.id),cleanups:t.store.cleanups(t.controlPlane.project.id),drills:t.store.drills(t.controlPlane.project.id)},i=[...n.manifests.map((o)=>["update",o.version,o.compatibility.compatible?"compatible":"blocked",o.compatibility.reasons.join("; ")||o.channel]),...n.campaigns.map((o)=>["upgrade",o.id,o.status,o.currentStage??o.fromVersion]),...n.cleanups.map((o)=>["cleanup",o.kind,o.status,`${o.candidates.length} items / ${o.estimatedBytes} bytes`]),...n.drills.map((o)=>["DR drill",o.scenario,o.status,o.isolatedTarget])];if(e.json)console.log(JSON.stringify(n,null,2));else x(["Area","Name / version","Status","Detail"],i)})),r.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(e,t)=>tt(async(n)=>{let i=n.store.addTrustedKey({organizationId:n.controlPlane.organization.id,name:e,publicKeyPem:await Bun.file(t).text()});h(`Trusted ${i.name}: ${i.fingerprint}`)})),r.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(e,t,n)=>tt(async(i)=>{let o=await Bun.file(e).json(),s=(await Bun.file(t).text()).trim(),c=i.store.importManifest({organizationId:i.controlPlane.organization.id,keyId:n,document:o,signature:s,current:{schemaVersion:i.controlPlane.store.health().schemaVersion,currentVersion:fn,platform:process.platform,architecture:process.arch}});h(`Verified ${c.version}; ${c.compatibility.compatible?"compatible":"blocked: "+c.compatibility.reasons.join("; ")}`)})),r.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(e,t,n)=>tt((i)=>{let o=i.store.createWindow({projectId:i.controlPlane.project.id,name:e,schedule:t,timezone:n.timezone,durationMinutes:Number(n.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});h(`Created ${o.name} (${o.id}).`)})),r.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(e,t,n)=>tt((i)=>{let o=new et(i.controlPlane.store).list(i.controlPlane.project.id).filter((l)=>l.status==="ready").map((l)=>({serverId:l.id,target:l.name,previousVersion:l.bootstrapVersion??fn}));if(!o.length)o.push({target:"control-plane",previousVersion:fn});let s=i.store.createCampaign({projectId:i.controlPlane.project.id,manifestId:e,fromVersion:fn,strategy:n.strategy==="rolling"?"rolling":"canary",batchSize:Number(n.batch),healthGate:{kind:"platform"},backupId:t,targets:o}),c=i.service.enqueueCampaign(s.id);h(`Staged upgrade queued: ${c.operation.id}`)})),r.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(e,t)=>tt(async(n)=>{let i=await n.service.previewCleanup({projectId:n.controlPlane.project.id,kind:e,criteria:{olderThanDays:Number(t.olderThan)}},n.cleanup);x(["ID","Candidate","Bytes"],i.candidates.map((o)=>[o.id,o.label,String(o.bytes)])),a(`Apply with: cloud cleanup:apply ${i.id} --confirm "DELETE ${i.candidates.length} ${i.kind}"`)})),r.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(e,t)=>tt((n)=>{let i=n.service.enqueueCleanup(e,String(t.confirm??""));h(`Cleanup queued: ${i.operation.id}`)})),r.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(e,t,n)=>tt((i)=>{let o=i.store.createDrill({projectId:i.controlPlane.project.id,scenario:e,isolatedTarget:t,expectedRpoMinutes:Number(n.rpo),expectedRtoMinutes:Number(n.rto),recoveryPointId:n.recoveryPoint,topologyId:n.topology});h(`Planned isolated drill ${o.id}.`)})),r.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(e)=>tt((t)=>{let n=t.service.enqueueDrill(e);h(`DR drill queued: ${n.operation.id}`)}))}async function oi(){try{return(await P()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function si(r){r.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(e)=>{S("Lambda Functions");let t=e?.region||await oi(),n=new nt(t);try{let{Functions:i=[]}=await n.listFunctions({MaxItems:50});if(!i.length){a("No functions found");return}x(["Name","Runtime","Memory","Timeout","Last Modified"],i.map((o)=>[o.FunctionName??"-",o.Runtime??"-",o.MemorySize?`${o.MemorySize} MB`:"-",o.Timeout?`${o.Timeout}s`:"-",o.LastModified??"-"]))}catch(i){f(`Failed to list functions: ${i.message}`),process.exitCode=1}}),r.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(e,t)=>{S(`Invoking ${e}`);let n=t?.region||await oi(),i=new nt(n),o=new A("Invoking function...");o.start();try{let s=await i.invoke({FunctionName:e,InvocationType:t?.async?"Event":"RequestResponse",Payload:t?.payload||"{}",LogType:t?.async?"None":"Tail"});if(s.FunctionError){if(o.fail(`Function returned an error (${s.FunctionError})`),s.Payload)a(s.Payload);process.exitCode=1;return}if(o.succeed(`Invoked (status ${s.StatusCode})`),s.Payload)a(`
|
|
319
319
|
Response:`),a(s.Payload);if(s.LogResult)a(`
|
|
320
320
|
Logs:`),a(Buffer.from(s.LogResult,"base64").toString("utf-8"))}catch(s){o.fail(`Invocation failed: ${s.message}`),process.exitCode=1}}),r.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(e,t)=>{S(`Logs for ${e}`);let n=t?.region||await oi(),i=new rt(n),o=e.startsWith("/aws/lambda/")?e:`/aws/lambda/${e}`,s=Number(t?.since??15),c=(l)=>{for(let d of l){let u=d.timestamp?new Date(d.timestamp).toISOString():"";a(`${u} ${(d.message??"").trimEnd()}`)}};try{let l=Date.now()-s*60000,{events:d=[]}=await i.filterLogEvents({logGroupName:o,startTime:l,filterPattern:t?.filter,limit:200});if(c(d),d.length)l=(d[d.length-1].timestamp??l)+1;if(t?.tail){a(`
|
|
321
321
|
(streaming — Ctrl+C to stop)`);for(;;){await new Promise((m)=>setTimeout(m,3000));let{events:u=[]}=await i.filterLogEvents({logGroupName:o,startTime:l,filterPattern:t?.filter,limit:200});if(u.length)c(u),l=(u[u.length-1].timestamp??l)+1}}}catch(l){f(`Failed to read logs: ${l.message}`),process.exitCode=1}})}async function Va(r){let e=Bun.spawn(["docker",...r],{stdin:"inherit",stdout:"inherit",stderr:"pipe"}),[t,n]=await Promise.all([e.exited,new Response(e.stderr).text()]);return{ok:t===0,exitCode:t,command:["docker",...r].join(" "),stderr:n.trim()}}function ai(r){r.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(e)=>{let t=["build","--file",e.file??"Dockerfile","--tag",e.tag??"latest","."];if(e.dryRun){console.log(`docker ${t.join(" ")}`);return}let n=await Va(t);if(e.json)console.log(JSON.stringify(n));if(!n.ok)f(n.stderr||`docker exited ${n.exitCode}`),process.exitCode=n.exitCode;else h(`Built ${e.tag??"latest"}.`)}),r.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(e)=>{if(!e.image){f("--image with a full registry reference is required; credentials must come from docker credential helpers."),process.exitCode=2;return}if(e.dryRun){console.log(`docker push ${e.image}`);return}let t=await Va(["push",e.image]);if(e.json)console.log(JSON.stringify(t));if(!t.ok)f(t.stderr),process.exitCode=t.exitCode;else h(`Pushed ${e.image}.`)}),r.command("container:deploy","Deploy a container image").action(async()=>be("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 gi(r){r.command("domain:list","List all domains").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(e)=>{S("Domains");try{let t=_e(e?.provider),n=ce(e?.provider)?.provider||"unknown",i=new A(`Fetching domains from ${n}...`);i.start();let o=await t.listDomains();if(i.succeed(`Found ${o.length} domain(s)`),o.length===0){a("No domains found in this provider");return}let s=o.map((c)=>[c,"Active","-",n.charAt(0).toUpperCase()+n.slice(1)]);x(["Domain","Status","SSL","Provider"],s)}catch(t){f(`Failed to list domains: ${t instanceof Error?t.message:String(t)}`)}}),r.command("domain:add <domain>","Add a new domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(e,t)=>{S(`Adding Domain: ${e}`);try{let n=_e(t?.provider),i=ce(t?.provider)?.provider||"unknown",o=new A(`Checking if ${i} can manage ${e}...`);if(o.start(),await n.canManageDomain(e))o.succeed(`Domain ${e} is already available in ${i}`),a(`
|
|
@@ -400,7 +400,7 @@ ${l.instanceId}:`),a(l.output?.trimEnd()||"(no output)")}catch(n){f(`History loo
|
|
|
400
400
|
`),{runComputeRecipe:c}=await import("./chunk-dkf4qsp2.js"),l=await c({driver:He({config:i}),slug:i.project.slug,environment:o,logger:z},{name:e,script:s,user:n?.user});for(let d of l.perInstance||[])a(`
|
|
401
401
|
${d.instanceId}:`),a(d.output?.trimEnd()||"(no output)");if(!l.success)process.exitCode=1}catch(i){f(`Recipe failed: ${i.message}`),process.exitCode=1}}),r.command("db:restore-backup [from]","Restore the app database from an on-box ts-backups dump (latest, or a given file)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t)=>{S("Database Restore");try{let n=await P(),i=t?.env||"production",{restoreDatabaseBackup:o}=await import("./chunk-dkf4qsp2.js"),s=await o({driver:He({config:n}),slug:n.project.slug,environment:i,logger:z},{database:_n(n),from:e});for(let c of s.perInstance||[])a(` ${c.instanceId}: ${c.output?.trim()||c.status}`);if(!s.success)f(`Restore failed: ${s.error||"unknown error"}`),process.exitCode=1}catch(n){f(`Restore failed: ${n.message}`),process.exitCode=1}}),r.command("quick-deploy","Generate a push-to-deploy CI pipeline for your git provider (Forge Quick Deploy)").option("--env <environment>","Environment to deploy on push",{default:"production"}).option("--provider <provider>","CI provider (github, gitlab, bitbucket); defaults to the origin remote").option("--site <site>","Deploy only this configured site").option("--skip-dns-verification","Generate a deploy that skips DNS verification and record creation").option("--ssh-key-secret <name>","CI secret/variable containing the Hetzner deployment SSH private key",{default:"SSH_PRIVATE_KEY"}).option("--force","Overwrite an existing pipeline file").action(async(e)=>{S("Quick Deploy (push-to-deploy)");try{let t=await P(),{buildQuickDeployCi:n,inferQuickDeployProvider:i}=await import("./chunk-hq9x489e.js"),o=e?.provider?.toLowerCase();if(o&&!["github","gitlab","bitbucket"].includes(o))throw Error(`Unsupported CI provider '${e?.provider}'. Use github, gitlab, or bitbucket.`);let s=o;if(!s)try{let l=Eo("git remote get-url origin",{stdio:["ignore","pipe","ignore"]}).toString().trim();s=i(l)}catch{}let c=n(t,e?.env||"production",{provider:s,site:e?.site,skipDnsVerification:e?.skipDnsVerification,setup:ge("pantry.lock")?"pantry":"bun",sshPrivateKeySecret:e?.sshKeySecret});if(!c){R("Could not resolve a GitHub, GitLab, or Bitbucket provider from --provider, the origin remote, or a configured site repository."),process.exitCode=1;return}if(ge(c.path)&&!e?.force){R(`${c.path} already exists — re-run with --force to overwrite.`);return}vl(np(c.path),{recursive:!0}),tp(c.path,c.content),h(`Wrote ${c.path} (${c.provider}, deploys on push to '${c.branch}').`),a("Next: commit it and add your provider credentials as CI secrets/variables.")}catch(t){f(`Quick deploy setup failed: ${t.message}`),process.exitCode=1}}),r.command("down","Put the serverless app into maintenance mode (503)").option("--env <environment>","Environment (production, staging, development)").option("--secret <secret>","Bypass secret (send as x-maintenance-bypass header)").action(async(e)=>{try{let t=await P(),n=e?.env||"production",{setMaintenance:i}=await import("./chunk-0zwknfwp.js");await i(t,n,!0,e?.secret)}catch(t){f(`Failed to enable maintenance mode: ${t.message}`),process.exitCode=1}}),r.command("up","Bring the serverless app out of maintenance mode").option("--env <environment>","Environment (production, staging, development)").action(async(e)=>{try{let t=await P(),n=e?.env||"production",{setMaintenance:i}=await import("./chunk-0zwknfwp.js");await i(t,n,!1)}catch(t){f(`Failed to disable maintenance mode: ${t.message}`),process.exitCode=1}}),r.command("command <cmd>","Run a command on the serverless CLI function (e.g. migrations)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t)=>{try{let n=await P(),i=t?.env||"production",{runAndRecordCommand:o}=await import("./chunk-0zwknfwp.js"),{id:s,output:c}=await o(n,i,e);if(a(c),s>0)a(`
|
|
402
402
|
(recorded as #${s} — re-run with \`cloud command:again ${s}\`)`)}catch(n){f(`Command failed: ${n.message}`),process.exitCode=1}}),r.command("command:history","List recorded CLI-function command invocations").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Show at most this many (most recent)",{default:"20"}).action(async(e)=>{try{let t=await P(),n=e?.env||"production",{listCommandHistory:i}=await import("./chunk-0zwknfwp.js"),o=await i(t,n);if(!o.length){a("No command history yet.");return}let s=Number(e?.limit??20);S(`Command history — ${t.project.slug} (${n})`),x(["#","When","Status","Command"],o.slice(-s).reverse().map((c)=>[String(c.id),c.timestamp,c.status,c.command]))}catch(t){f(`Failed to read history: ${t.message}`),process.exitCode=1}}),r.command("command:again [id]","Re-run a recorded command (defaults to the most recent)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t)=>{try{let n=await P(),i=t?.env||"production",{getCommandRecord:o,runAndRecordCommand:s}=await import("./chunk-0zwknfwp.js"),c=await o(n,i,e?Number(e):void 0);if(!c){f(e?`No command #${e} in history.`:"No command history to re-run."),process.exitCode=1;return}a(`Re-running #${c.id}: ${c.command}`);let l=await s(n,i,c.command);if(a(l.output),l.id>0)a(`
|
|
403
|
-
(recorded as #${l.id})`)}catch(n){f(`Command failed: ${n.message}`),process.exitCode=1}}),r.command("serverless:db-shell <sql>","Run a SQL statement against a private serverless database (via the CLI function)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t)=>{try{let n=await P(),i=t?.env||"production",{runDbQuery:o}=await import("./chunk-0zwknfwp.js"),s=await o(n,i,e);a(s)}catch(n){f(`Query failed: ${n.message}`),process.exitCode=1}}),r.command("serverless:db-scale <min> <max>","Rescale the serverless Aurora cluster (min/max ACUs)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t,n)=>{S("Scaling serverless database");try{let i=await P(),o=n?.env||"production",s=Number(e),c=Number(t);if(!(s>0)||!(c>=s)){f("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:l}=await import("./chunk-0zwknfwp.js");await l(i,o,s,c)}catch(i){f(`Scale failed: ${i.message}`),process.exitCode=1}}),r.command("serverless:db-restore","Restore the serverless Aurora cluster to a point in time (as a new cluster)").option("--env <environment>","Environment (production, staging, development)").option("--to <timestamp>","Restore to this ISO-8601 time (UTC)").option("--latest","Restore to the latest restorable time").option("--target <id>","New cluster identifier (defaults to <cluster>-restore-<stamp>)").action(async(e)=>{S("Restoring serverless database");try{let t=await P(),n=e?.env||"production",i;if(e?.to){if(i=new Date(e.to),Number.isNaN(i.getTime())){f(`Invalid --to timestamp: ${e.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:o}=await import("./chunk-0zwknfwp.js");await o(t,n,{toTime:i,latest:e?.latest,target:e?.target})}catch(t){f(`Restore failed: ${t.message}`),process.exitCode=1}}),r.command("serverless:info","Show an operational summary of a deployed serverless app").option("--env <environment>","Environment (production, staging, development)").action(async(e)=>{try{let t=await P(),n=e?.env||"production",{serverlessInfo:i}=await import("./chunk-0zwknfwp.js"),o=await i(t,n);if(S(`${o.slug} (${o.environment})`),a(`Stack: ${o.stackStatus}`),a(`Region: ${o.region}`),o.endpoint)a(`URL: ${o.endpoint}`);if(o.assetUrl)a(`Assets: ${o.assetUrl}`);if(a(`Scheduler:${o.scheduler==="off"?" off":` ${o.scheduler}`}`),a(`Queues: ${o.queues.length?o.queues.join(", "):"none"}`),a(`Warming: ${o.provisionedConcurrency>0?`provisioned concurrency ×${o.provisionedConcurrency}`:"none / ping-warm"}`),o.lastRelease)a(`Release: ${o.lastRelease.sha.slice(0,12)} @ ${o.lastRelease.timestamp}`);x(["Function","Version","Provisioned"],o.functions.map((s)=>[s.name,s.version,s.provisioned?`${s.provisioned.status} ${s.provisioned.allocated}/${s.provisioned.requested}`:"—"]))}catch(t){f(`Failed to read info: ${t.message}`),process.exitCode=1}}),r.command("dashboard:build","Build the management dashboard with live data baked in").option("--env <environment>","Environment (production, staging, development)").option("--ui <dir>","UI directory (default ./ui)",{default:"ui"}).action(async(e)=>{S("Building management dashboard (live data)");try{let{existsSync:t}=await import("node:fs"),n=e?.ui||"ui";if(!t(`${n}/package.json`)){f(`No UI project at ${n}/ (expected ${n}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let i=await P(),o=e?.env||"production";M("Gathering live data from AWS");let s=null;if(i.environments?.[o]?.app){let{resolveDashboardData:u}=await import("./chunk-f06c5np9.js"),m=await u(i,o).catch((p)=>(R(`Serverless data unavailable (${p.message}) — that view uses sample data.`),null));if(m)s={...s??{},...m}}if(i.infrastructure?.compute){let{resolveServerDashboardData:u}=await import("./chunk-
|
|
403
|
+
(recorded as #${l.id})`)}catch(n){f(`Command failed: ${n.message}`),process.exitCode=1}}),r.command("serverless:db-shell <sql>","Run a SQL statement against a private serverless database (via the CLI function)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t)=>{try{let n=await P(),i=t?.env||"production",{runDbQuery:o}=await import("./chunk-0zwknfwp.js"),s=await o(n,i,e);a(s)}catch(n){f(`Query failed: ${n.message}`),process.exitCode=1}}),r.command("serverless:db-scale <min> <max>","Rescale the serverless Aurora cluster (min/max ACUs)").option("--env <environment>","Environment (production, staging, development)").action(async(e,t,n)=>{S("Scaling serverless database");try{let i=await P(),o=n?.env||"production",s=Number(e),c=Number(t);if(!(s>0)||!(c>=s)){f("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:l}=await import("./chunk-0zwknfwp.js");await l(i,o,s,c)}catch(i){f(`Scale failed: ${i.message}`),process.exitCode=1}}),r.command("serverless:db-restore","Restore the serverless Aurora cluster to a point in time (as a new cluster)").option("--env <environment>","Environment (production, staging, development)").option("--to <timestamp>","Restore to this ISO-8601 time (UTC)").option("--latest","Restore to the latest restorable time").option("--target <id>","New cluster identifier (defaults to <cluster>-restore-<stamp>)").action(async(e)=>{S("Restoring serverless database");try{let t=await P(),n=e?.env||"production",i;if(e?.to){if(i=new Date(e.to),Number.isNaN(i.getTime())){f(`Invalid --to timestamp: ${e.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:o}=await import("./chunk-0zwknfwp.js");await o(t,n,{toTime:i,latest:e?.latest,target:e?.target})}catch(t){f(`Restore failed: ${t.message}`),process.exitCode=1}}),r.command("serverless:info","Show an operational summary of a deployed serverless app").option("--env <environment>","Environment (production, staging, development)").action(async(e)=>{try{let t=await P(),n=e?.env||"production",{serverlessInfo:i}=await import("./chunk-0zwknfwp.js"),o=await i(t,n);if(S(`${o.slug} (${o.environment})`),a(`Stack: ${o.stackStatus}`),a(`Region: ${o.region}`),o.endpoint)a(`URL: ${o.endpoint}`);if(o.assetUrl)a(`Assets: ${o.assetUrl}`);if(a(`Scheduler:${o.scheduler==="off"?" off":` ${o.scheduler}`}`),a(`Queues: ${o.queues.length?o.queues.join(", "):"none"}`),a(`Warming: ${o.provisionedConcurrency>0?`provisioned concurrency ×${o.provisionedConcurrency}`:"none / ping-warm"}`),o.lastRelease)a(`Release: ${o.lastRelease.sha.slice(0,12)} @ ${o.lastRelease.timestamp}`);x(["Function","Version","Provisioned"],o.functions.map((s)=>[s.name,s.version,s.provisioned?`${s.provisioned.status} ${s.provisioned.allocated}/${s.provisioned.requested}`:"—"]))}catch(t){f(`Failed to read info: ${t.message}`),process.exitCode=1}}),r.command("dashboard:build","Build the management dashboard with live data baked in").option("--env <environment>","Environment (production, staging, development)").option("--ui <dir>","UI directory (default ./ui)",{default:"ui"}).action(async(e)=>{S("Building management dashboard (live data)");try{let{existsSync:t}=await import("node:fs"),n=e?.ui||"ui";if(!t(`${n}/package.json`)){f(`No UI project at ${n}/ (expected ${n}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let i=await P(),o=e?.env||"production";M("Gathering live data from AWS");let s=null;if(i.environments?.[o]?.app){let{resolveDashboardData:u}=await import("./chunk-f06c5np9.js"),m=await u(i,o).catch((p)=>(R(`Serverless data unavailable (${p.message}) — that view uses sample data.`),null));if(m)s={...s??{},...m}}if(i.infrastructure?.compute){let{resolveServerDashboardData:u}=await import("./chunk-z3qz1713.js"),m=await u(i,o).catch(()=>null);if(m){if(m._serverReachable===!1)R("Server box not reachable over SSM — server view uses config + sample data.");s={...s??{},...m}}}M("Building dashboard");let{encodeDashboardPayload:c}=await import("./chunk-djg4zyqk.js"),{execSync:l}=await import("node:child_process"),{rmSync:d}=await import("node:fs");for(let u of[".stx/ssg-cache",".stx/cache"])d(`${n}/${u}`,{recursive:!0,force:!0});l("bun run build",{cwd:n,stdio:"inherit",env:{...process.env,...s?{TSCLOUD_DASHBOARD_DATA:c(s)}:{}}}),h(`Dashboard built → ${n}/dist${s?" (live data)":" (sample data)"}`)}catch(t){f(`Dashboard build failed: ${t.message}`),process.exitCode=1}}),r.command("serverless:build-php-layer","Build + publish the ts-cloud PHP runtime layer (requires Docker)").option("--arch <architecture>","x86_64 or arm64",{default:"x86_64"}).option("--php <version>","PHP version",{default:"8.3"}).option("--name <name>","Layer name",{default:"tscloud-php"}).option("--bucket <bucket>","S3 bucket to stage the layer zip (defaults to {slug}-layers)").option("--region <region>","AWS region").action(async(e)=>{S("Building PHP runtime layer");try{let t=await P().catch(()=>null),n=e?.region||t?.project.region||"us-east-1",i=e?.arch||"x86_64",o=e?.php||"8.3",s=`${e?.name||"tscloud-php"}-${o.replace(".","")}-${i}`,c=e?.bucket||`${t?.project.slug||"tscloud"}-layers`,{buildPhpRuntimeLayerZip:l}=await import("./chunk-k3120rx6.js"),{S3Client:d}=await import("./chunk-zh2d4704.js"),{LambdaClient:u}=await import("./chunk-dkaz333b.js"),m=l({architecture:i,phpVersion:o,onStep:(b)=>M(b)});a(`Layer: ${m.fileCount} files, ${(m.zip.length/1024/1024).toFixed(1)} MB`);let p=new d(n);if(!await p.bucketExists(c))M(`Creating layer bucket ${c}`),await p.createBucket(c);let y=`layers/${s}.zip`;M("Uploading layer zip"),await p.putObject({bucket:c,key:y,body:m.zip,contentType:"application/zip"}),M("Publishing layer version");let g=await new u(n).publishLayerVersion({LayerName:s,Description:`ts-cloud PHP ${o} runtime (${i})`,Content:{S3Bucket:c,S3Key:y},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[i]});Xe(["PHP runtime layer published","",`ARN: ${g.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'php', layers: ['${g.LayerVersionArn}'] }`,"or set TSCLOUD_PHP_LAYER_ARN before deploying."].join(`
|
|
404
404
|
`),"green")}catch(t){f(`Layer build failed: ${t.message}`),process.exitCode=1}}),r.command("serverless:build-node-layer","Build + publish a ts-cloud Node custom runtime layer (any version, incl. 24)").option("--arch <architecture>","x86_64 or arm64",{default:"x86_64"}).option("--node <version>","Node version (e.g. 24)",{default:"24"}).option("--name <name>","Layer name",{default:"tscloud-node"}).option("--bucket <bucket>","S3 bucket to stage the layer zip (defaults to {slug}-layers)").option("--region <region>","AWS region").action(async(e)=>{S("Building Node runtime layer");try{let t=await P().catch(()=>null),n=e?.region||t?.project.region||"us-east-1",i=e?.arch||"x86_64",o=e?.node||"24",{buildNodeRuntimeLayerZip:s}=await import("./chunk-k3120rx6.js"),{S3Client:c}=await import("./chunk-zh2d4704.js"),{LambdaClient:l}=await import("./chunk-dkaz333b.js"),d=s({architecture:i,version:o,onStep:(b)=>M(b)}),u=`${e?.name||"tscloud-node"}-${d.version.split(".")[0]}-${i}`,m=e?.bucket||`${t?.project.slug||"tscloud"}-layers`;a(`Layer: Node ${d.version}, ${(d.zip.length/1024/1024).toFixed(1)} MB`);let p=new c(n);if(!await p.bucketExists(m))M(`Creating layer bucket ${m}`),await p.createBucket(m);let y=`layers/${u}.zip`;M("Uploading layer zip"),await p.putObject({bucket:m,key:y,body:d.zip,contentType:"application/zip"}),M("Publishing layer version");let g=await new l(n).publishLayerVersion({LayerName:u,Description:`ts-cloud Node ${d.version} runtime (${i})`,Content:{S3Bucket:m,S3Key:y},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[i]});Xe(["Node runtime layer published","",`ARN: ${g.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'node', runtimeVersion: '${d.version.split(".")[0]}', layers: ['${g.LayerVersionArn}'] }`,"or set TSCLOUD_NODE_LAYER_ARN before deploying."].join(`
|
|
405
405
|
`),"green")}catch(t){f(`Layer build failed: ${t.message}`),process.exitCode=1}}),r.command("serverless:build-bun-layer","Build + publish a ts-cloud Bun custom runtime layer").option("--arch <architecture>","x86_64 or arm64",{default:"x86_64"}).option("--bun <version>",'Bun version (e.g. 1.3.13, or "latest")',{default:"latest"}).option("--name <name>","Layer name",{default:"tscloud-bun"}).option("--bucket <bucket>","S3 bucket to stage the layer zip (defaults to {slug}-layers)").option("--region <region>","AWS region").action(async(e)=>{S("Building Bun runtime layer");try{let t=await P().catch(()=>null),n=e?.region||t?.project.region||"us-east-1",i=e?.arch||"x86_64",o=e?.bun||"latest",{buildBunRuntimeLayerZip:s}=await import("./chunk-k3120rx6.js"),{S3Client:c}=await import("./chunk-zh2d4704.js"),{LambdaClient:l}=await import("./chunk-dkaz333b.js"),d=s({architecture:i,version:o,onStep:(b)=>M(b)}),u=`${e?.name||"tscloud-bun"}-${d.version.replace(/\./g,"")}-${i}`,m=e?.bucket||`${t?.project.slug||"tscloud"}-layers`;a(`Layer: Bun ${d.version}, ${(d.zip.length/1024/1024).toFixed(1)} MB`);let p=new c(n);if(!await p.bucketExists(m))M(`Creating layer bucket ${m}`),await p.createBucket(m);let y=`layers/${u}.zip`;M("Uploading layer zip"),await p.putObject({bucket:m,key:y,body:d.zip,contentType:"application/zip"}),M("Publishing layer version");let g=await new l(n).publishLayerVersion({LayerName:u,Description:`ts-cloud Bun ${d.version} runtime (${i})`,Content:{S3Bucket:m,S3Key:y},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[i]});Xe(["Bun runtime layer published","",`ARN: ${g.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'bun', layers: ['${g.LayerVersionArn}'] }`,"or set TSCLOUD_BUN_LAYER_ARN before deploying."].join(`
|
|
406
406
|
`),"green")}catch(t){f(`Layer build failed: ${t.message}`),process.exitCode=1}}),r.command("deploy:status","Check deployment status").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(e)=>{S("Deployment Status");try{let t=await P(),n=e?.env||"production",i=e?.stack||we(t,n),o=t.project.region||"us-east-1";a(`Stack: ${i}`),a(`Region: ${o}`);let s=new A("Checking deployment status...");s.start();let l=await new ie(o).describeStacks({stackName:i});if(l.Stacks.length===0){s.fail("Stack not found"),hn("No deployment found for this environment");return}let d=l.Stacks[0];if(s.succeed("Status retrieved"),a(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Wa as i}from"./chunk-
|
|
1
|
+
import{Wa as i}from"./chunk-j91jb1nx.js";import"./chunk-sj5csg49.js";import"./chunk-tfbs8k8v.js";import"./chunk-s4yzes15.js";import"./chunk-3aph4c1w.js";import"./chunk-mfrf9q4b.js";import"./chunk-82mj52xr.js";import"./chunk-7zhgmp1s.js";import"./chunk-e2bybahr.js";import"./chunk-d7ke90zt.js";import"./chunk-kg61p5hw.js";import"./chunk-c0bdafbx.js";import"./chunk-xdqq98wp.js";import"./chunk-rtecnmts.js";import"./chunk-8ewncfce.js";import"./chunk-9kf0np8j.js";import"./chunk-xk08030d.js";import"./chunk-x6f61g36.js";import"./chunk-xhwqpgwq.js";import"./chunk-a7w13qfm.js";import"./chunk-my3ewh3a.js";import"./chunk-e5ab5twy.js";import"./chunk-btsyjhk7.js";import"./chunk-w32xv8n4.js";import"./chunk-dz1ec589.js";import"./chunk-9a88fp00.js";import"./chunk-6tfwm33r.js";import"./chunk-ja1vjdn1.js";import"./chunk-4q6tad44.js";import"./chunk-ehc63fvs.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 a(){let o=await i({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)})}a();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ud as Sp}from"./chunk-h42zck7h.js";import{Bd as to,Cd as zp,Dd as rs,Ed as Mt,Fd as ct,Gd as os,Hd as Up}from"./chunk-3mgj3hrh.js";import{Jd as ci,Kd as Vs,Oe as Fv,Pe as Ls,Rd as Zp,Td as xa,Ud as Yr,Wd as _n,Xd as kt,Yd as di,nf as Xp}from"./chunk-t0xgmhd6.js";import{of as ts}from"./chunk-m8fs0233.js";import{sf as Rn}from"./chunk-by2bwzk6.js";import{tf as Pp}from"./chunk-73ztr55z.js";import{uf as Fn}from"./chunk-xcj8zfmg.js";import{Jg as Ty,Jh as Wu,Mh as Ga,Rg as ir,cg as Bo,dg as rv,eg as nv,fg as vu,gg as Cu,hg as yv,jg as yn,og as zr,xh as vv,yh as bv}from"./chunk-xdpy9p7n.js";import{Wh as Hb}from"./chunk-aj025v2s.js";import{Xh as Er}from"./chunk-wavjkdb8.js";import{Yh as Qp,Zh as ur}from"./chunk-152he7m3.js";import{$h as mi,ai as Gp}from"./chunk-mz0dk78z.js";import{Ak as qb,Di as xb,Dj as Hm,Dk as pb,Ei as Db,Ek as Vb,Hi as Ps,Hk as tc,Ii as $e,Ik as Wb,Ji as Ob,Ki as Bm,Li as vs,Oi as $b,Pi as Nb,Ui as jb,Vi as Mb,Vk as ie,Wi as Bb,Xi as Lb,Xk as qc,Yk as Jm,Zk as Wm,aj as bs,ei as Es,fi as fp,hi as Xt,ii as Wo,ik as Km,pi as Oe,qi as hp,qk as Fb,ri as Tb,tk as zb,uk as Gi,vi as ys,yk as qo,zk as Ub}from"./chunk-86ss83s2.js";import{$l as gt,Bs as jp,Cs as ds,Ds as Mp,Es as Bp,Tl as bh,Vl as ho,Wl as yt,Xl as Cp,Zl as Fr,em as Zl,gn as Ep,ln as Rp,lt as Lp,rm as ui,rt as Fp,sm as Dp,tm as Op,ys as $p,zs as Np}from"./chunk-jm5mg890.js";import{Et as rt}from"./chunk-13qjvbqh.js";import{createHash as dS}from"node:crypto";function lS(e){return dS("sha256").update(En(e)).digest("hex")}function En(e){if(Array.isArray(e))return`[${e.map((t)=>En(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${En(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function Ye(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function yp(e,t){let r=new hp({cwd:e}),n=lS(t),i=r.getProjectBySlug(t.project.slug),o=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,s=(i?.organizationId?r.getOrganization(i.organizationId):void 0)??r.getOrganizationBySlug(o)??r.createOrganization({id:i?.organizationId,slug:o,name:t.project.name}),c=i?i.name!==t.project.name||i.desiredConfigHash!==n||i.organizationId!==s.id?r.updateProject(i.id,i.version,{name:t.project.name,organizationId:s.id,desiredConfigHash:n}):i:r.createProject({organizationId:s.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:n}),d=new Map;for(let[h,y]of Object.entries(t.environments??{})){let k=r.getEnvironmentBySlug(c.id,h)??r.createEnvironment({projectId:c.id,slug:h,name:h.replace(/(^|[-_])(\w)/g,(O,U,q)=>q.toUpperCase()),kind:String(y?.type??h),region:y?.region??t.project.region,desiredState:Oe(y)});d.set(h,k);let C=new Map(r.listResources(c.id,k.id).map((O)=>[`${O.kind}:${O.slug}`,O])),T=(O,U,q,N)=>{let Q=`${O}:${U}`,D=C.get(Q),Y=Oe(N);if(D){if(D.name!==q||En(D.desiredState)!==En(Y))C.set(Q,r.updateResource(D.id,D.version,{name:q,desiredState:Y}));return}let se=r.createResource({projectId:c.id,environmentId:k.id,kind:O,slug:U,name:q,provider:t.cloud?.provider,desiredState:Y,metadata:{source:"cloud-config"}});C.set(Q,se)};for(let[O,U]of Object.entries(t.sites??{}))T("application",O,O,U);let j=y?.app;if(j)for(let O of["http","queue","cli"])T("function",O,`${O.toUpperCase()} function`,{...Oe(j),function:O});let P=t.infrastructure;for(let[O,U]of Object.entries(P?.functions??{}))T("function",O,O,U);if(P?.compute)T("server",`${c.slug}-server`,c.name,{...Oe(P.compute),label:c.name});for(let[O,U]of Object.entries(P?.databases??{}))T("database",O,O,U);if(P?.appDatabase)T("database","application-database","Application database",P.appDatabase);else if(P?.database)T("database","application-database","Application database",{engine:P.database})}let a=new $e(r).recoverExpired(),u=r.reconcileOrphanedOperations({policy:"fail"}),m={requeued:a.requeued+u.requeued,failed:a.failed+a.cancelled+u.failed};return{store:r,organization:s,project:c,environments:d,reconciliation:m}}var uS=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function es(e,t){let{store:r,organization:n,project:i}=e,o=new Set;for(let s of t){let c=Ye(r,s);o.add(c.id);let d=r.getMembershipForActor(n.id,c.id);if(d&&d.source!=="legacy")continue;let a=r.listResources(i.id).filter((w)=>w.kind==="application"&&Object.hasOwn(s.sites,w.slug)),u=s.role==="admin"?"owner":"viewer",m=s.role==="admin"||a.length===0?{type:"organization"}:{type:"resource",id:a[0].id},h=d?d.roleTemplate!==u||En(d.scope)!==En(m)?r.updateMembership({id:d.id,roleTemplate:u,scope:m,actorId:c.id}):d:r.createMembership({organizationId:n.id,actorId:c.id,roleTemplate:u,scope:m,source:"legacy"}),y=new Set;if(s.role==="member"&&a.length===0)for(let w of fp("viewer"))y.add(`deny|${w}|organization|`);for(let w of a){let k=s.sites[w.slug];for(let C of uS)y.add(`allow|${C}|resource|${w.id}`);if(k==="owner")y.add(`allow|config:write|resource|${w.id}`)}for(let w of r.listGrants(h.id).filter((k)=>k.source==="legacy")){let k=`${w.effect}|${w.capability}|${w.scope.type}|${w.scope.id??""}`;if(!y.has(k))r.removeGrant(w.id,c.id)}for(let w of y){let[k,C,T,j]=w.split("|");r.upsertGrant({organizationId:n.id,membershipId:h.id,effect:k,capability:C,scope:T==="organization"?{type:"organization"}:{type:T,id:j},source:"legacy"})}}for(let s of r.listMemberships(n.id))if(s.source==="legacy"&&!o.has(s.actorId))r.revokeMembership(s.id)}async function Ir(e){let{controlPlane:t,environment:r,actor:n}=e,i=Ye(t.store,n),o=t.environments.get(r),s=e.resourceSlug&&o?t.store.listResources(t.project.id,o.id).find((u)=>u.slug===e.resourceSlug):void 0,c=new $e(t.store,{workerId:`dashboard:${process.pid}`}),d=c.enqueue({projectId:t.project.id,environmentId:o?.id,resourceId:s?.id,actorId:i.id,kind:e.kind,input:e.input??{},lockKey:s?`resource:${s.id}`:o?`environment:${o.id}`:`project:${t.project.id}`,providerKey:s?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!c.claim(d.id)?.operation)throw Error(`Could not claim control-plane operation ${d.id}`);try{let u=await e.execute(),m=typeof u.stdout==="string"?String(u.stdout):"",h=typeof u.stderr==="string"?String(u.stderr):"";if(m)c.appendLog(d.id,m,{stream:"stdout"});if(h)c.appendLog(d.id,h,{stream:"stderr"});let y=u.ok?c.complete(d.id,gp(u)):c.fail(d.id,pS(u),gp(u));return{result:u,operation:y}}catch(u){throw c.fail(d.id,u instanceof Error?u.message:String(u),{ok:!1,threw:!0}),u}}function pS(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function gp(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",n=typeof t.stderr==="string"?t.stderr:"",i={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(n)};if(typeof t.operation==="string")i.operation=t.operation;if(typeof t.error==="string")i.error=t.error;return Oe(i)}var vp=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],mS=new Map(vp.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function bp(e){return mS.get(e)}function U_(e,t){return vp.filter((r)=>r.modes.includes(e)&&(!t||!r.adminOnly))}import Qr from"node:process";import{existsSync as gS}from"node:fs";import{join as fS}from"node:path";async function J_(e){let t=Date.now(),r=e.sourceDir??"dist";if(!gS(fS(r,"index.html")))return mc(t,`${r}/ has no index.html — build first.`);if(!Qr.env.AWS_ACCESS_KEY_ID||!Qr.env.AWS_SECRET_ACCESS_KEY)return mc(t,"Missing AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY in env.");let n=hS(e.dnsProvider);if("error"in n)return mc(t,n.error);let i=await Sp({siteName:e.siteName,region:e.region??"us-east-1",domain:e.domain,bucket:e.bucket,stackName:e.stackName,certificateArn:e.certificateArn,defaultRootObject:e.defaultRootObject??"index.html",errorDocument:e.errorDocument??"404.html",cacheControl:e.cacheControl??"max-age=3600, public",sourceDir:r,cleanBucket:e.cleanBucket??!1,singlePageApp:e.singlePageApp??!1,dnsProvider:n,tags:{ManagedBy:"ts-cloud",Application:e.siteName,...e.tags},onProgress:e.onProgress});return{success:!!i.success,domain:i.domain,url:i.domain?`https://${i.domain}`:i.distributionDomain?`https://${i.distributionDomain}`:void 0,bucket:i.bucket,distributionId:i.distributionId,distributionDomain:i.distributionDomain,certificateArn:i.certificateArn,filesUploaded:i.filesUploaded,filesSkipped:i.filesSkipped,message:i.message,durationMs:Date.now()-t}}function hS(e){let t=typeof e==="string"?{provider:e}:e??{provider:"porkbun"};if(t.provider==="porkbun"){let r=t,n=r?.apiKey??Qr.env.PORKBUN_API_KEY,i=r?.secretKey??Qr.env.PORKBUN_SECRET_KEY??Qr.env.PORKBUN_SECRET_API_KEY;if(!n||!i)return{error:"Missing PORKBUN_API_KEY / PORKBUN_SECRET_KEY in env."};return{provider:"porkbun",apiKey:n,secretKey:i}}if(t.provider==="godaddy"){let r=t,n=r?.apiKey??Qr.env.GODADDY_API_KEY,i=r?.secretKey??Qr.env.GODADDY_API_SECRET,o=r?.environment??Qr.env.GODADDY_ENVIRONMENT;if(!n||!i)return{error:"Missing GODADDY_API_KEY / GODADDY_API_SECRET in env."};return{provider:"godaddy",apiKey:n,apiSecret:i,environment:o}}return{error:`Unsupported DNS provider: ${t.provider}`}}function mc(e,t){return{success:!1,message:t,durationMs:Date.now()-e}}import{createHash as yS}from"node:crypto";var vS=`let coldStart = true
|
|
1
|
+
import{ud as Sp}from"./chunk-h42zck7h.js";import{Bd as to,Cd as zp,Dd as rs,Ed as Mt,Fd as ct,Gd as os,Hd as Up}from"./chunk-3mgj3hrh.js";import{Jd as ci,Kd as Vs,Oe as Fv,Pe as Ls,Rd as Zp,Td as xa,Ud as Yr,Wd as _n,Xd as kt,Yd as di,nf as Xp}from"./chunk-t0xgmhd6.js";import{of as ts}from"./chunk-m8fs0233.js";import{sf as Rn}from"./chunk-by2bwzk6.js";import{tf as Pp}from"./chunk-73ztr55z.js";import{uf as Fn}from"./chunk-xcj8zfmg.js";import{Jh as Wu,Mh as Ga,Pg as Ty,Xg as ir,cg as Bo,dg as rv,eg as nv,fg as vu,gg as Cu,hg as yv,jg as yn,og as zr,xh as vv,yh as bv}from"./chunk-kp6mgc9b.js";import{Wh as Hb}from"./chunk-aj025v2s.js";import{Xh as Er}from"./chunk-wavjkdb8.js";import{Yh as Qp,Zh as ur}from"./chunk-152he7m3.js";import{$h as mi,ai as Gp}from"./chunk-mz0dk78z.js";import{Ak as qb,Di as xb,Dj as Hm,Dk as pb,Ei as Db,Ek as Vb,Hi as Ps,Hk as tc,Ii as $e,Ik as Wb,Ji as Ob,Ki as Bm,Li as vs,Oi as $b,Pi as Nb,Ui as jb,Vi as Mb,Vk as ie,Wi as Bb,Xi as Lb,Xk as qc,Yk as Jm,Zk as Wm,aj as bs,ei as Es,fi as fp,hi as Xt,ii as Wo,ik as Km,pi as Oe,qi as hp,qk as Fb,ri as Tb,tk as zb,uk as Gi,vi as ys,yk as qo,zk as Ub}from"./chunk-86ss83s2.js";import{$l as gt,Bs as jp,Cs as ds,Ds as Mp,Es as Bp,Tl as bh,Vl as ho,Wl as yt,Xl as Cp,Zl as Fr,em as Zl,gn as Ep,ln as Rp,lt as Lp,rm as ui,rt as Fp,sm as Dp,tm as Op,ys as $p,zs as Np}from"./chunk-jm5mg890.js";import{Et as rt}from"./chunk-13qjvbqh.js";import{createHash as dS}from"node:crypto";function lS(e){return dS("sha256").update(En(e)).digest("hex")}function En(e){if(Array.isArray(e))return`[${e.map((t)=>En(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${En(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function Ye(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function yp(e,t){let r=new hp({cwd:e}),n=lS(t),i=r.getProjectBySlug(t.project.slug),o=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,s=(i?.organizationId?r.getOrganization(i.organizationId):void 0)??r.getOrganizationBySlug(o)??r.createOrganization({id:i?.organizationId,slug:o,name:t.project.name}),c=i?i.name!==t.project.name||i.desiredConfigHash!==n||i.organizationId!==s.id?r.updateProject(i.id,i.version,{name:t.project.name,organizationId:s.id,desiredConfigHash:n}):i:r.createProject({organizationId:s.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:n}),d=new Map;for(let[h,y]of Object.entries(t.environments??{})){let k=r.getEnvironmentBySlug(c.id,h)??r.createEnvironment({projectId:c.id,slug:h,name:h.replace(/(^|[-_])(\w)/g,(O,U,q)=>q.toUpperCase()),kind:String(y?.type??h),region:y?.region??t.project.region,desiredState:Oe(y)});d.set(h,k);let C=new Map(r.listResources(c.id,k.id).map((O)=>[`${O.kind}:${O.slug}`,O])),T=(O,U,q,N)=>{let Q=`${O}:${U}`,D=C.get(Q),Y=Oe(N);if(D){if(D.name!==q||En(D.desiredState)!==En(Y))C.set(Q,r.updateResource(D.id,D.version,{name:q,desiredState:Y}));return}let se=r.createResource({projectId:c.id,environmentId:k.id,kind:O,slug:U,name:q,provider:t.cloud?.provider,desiredState:Y,metadata:{source:"cloud-config"}});C.set(Q,se)};for(let[O,U]of Object.entries(t.sites??{}))T("application",O,O,U);let j=y?.app;if(j)for(let O of["http","queue","cli"])T("function",O,`${O.toUpperCase()} function`,{...Oe(j),function:O});let P=t.infrastructure;for(let[O,U]of Object.entries(P?.functions??{}))T("function",O,O,U);if(P?.compute)T("server",`${c.slug}-server`,c.name,{...Oe(P.compute),label:c.name});for(let[O,U]of Object.entries(P?.databases??{}))T("database",O,O,U);if(P?.appDatabase)T("database","application-database","Application database",P.appDatabase);else if(P?.database)T("database","application-database","Application database",{engine:P.database})}let a=new $e(r).recoverExpired(),u=r.reconcileOrphanedOperations({policy:"fail"}),m={requeued:a.requeued+u.requeued,failed:a.failed+a.cancelled+u.failed};return{store:r,organization:s,project:c,environments:d,reconciliation:m}}var uS=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function es(e,t){let{store:r,organization:n,project:i}=e,o=new Set;for(let s of t){let c=Ye(r,s);o.add(c.id);let d=r.getMembershipForActor(n.id,c.id);if(d&&d.source!=="legacy")continue;let a=r.listResources(i.id).filter((w)=>w.kind==="application"&&Object.hasOwn(s.sites,w.slug)),u=s.role==="admin"?"owner":"viewer",m=s.role==="admin"||a.length===0?{type:"organization"}:{type:"resource",id:a[0].id},h=d?d.roleTemplate!==u||En(d.scope)!==En(m)?r.updateMembership({id:d.id,roleTemplate:u,scope:m,actorId:c.id}):d:r.createMembership({organizationId:n.id,actorId:c.id,roleTemplate:u,scope:m,source:"legacy"}),y=new Set;if(s.role==="member"&&a.length===0)for(let w of fp("viewer"))y.add(`deny|${w}|organization|`);for(let w of a){let k=s.sites[w.slug];for(let C of uS)y.add(`allow|${C}|resource|${w.id}`);if(k==="owner")y.add(`allow|config:write|resource|${w.id}`)}for(let w of r.listGrants(h.id).filter((k)=>k.source==="legacy")){let k=`${w.effect}|${w.capability}|${w.scope.type}|${w.scope.id??""}`;if(!y.has(k))r.removeGrant(w.id,c.id)}for(let w of y){let[k,C,T,j]=w.split("|");r.upsertGrant({organizationId:n.id,membershipId:h.id,effect:k,capability:C,scope:T==="organization"?{type:"organization"}:{type:T,id:j},source:"legacy"})}}for(let s of r.listMemberships(n.id))if(s.source==="legacy"&&!o.has(s.actorId))r.revokeMembership(s.id)}async function Ir(e){let{controlPlane:t,environment:r,actor:n}=e,i=Ye(t.store,n),o=t.environments.get(r),s=e.resourceSlug&&o?t.store.listResources(t.project.id,o.id).find((u)=>u.slug===e.resourceSlug):void 0,c=new $e(t.store,{workerId:`dashboard:${process.pid}`}),d=c.enqueue({projectId:t.project.id,environmentId:o?.id,resourceId:s?.id,actorId:i.id,kind:e.kind,input:e.input??{},lockKey:s?`resource:${s.id}`:o?`environment:${o.id}`:`project:${t.project.id}`,providerKey:s?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!c.claim(d.id)?.operation)throw Error(`Could not claim control-plane operation ${d.id}`);try{let u=await e.execute(),m=typeof u.stdout==="string"?String(u.stdout):"",h=typeof u.stderr==="string"?String(u.stderr):"";if(m)c.appendLog(d.id,m,{stream:"stdout"});if(h)c.appendLog(d.id,h,{stream:"stderr"});let y=u.ok?c.complete(d.id,gp(u)):c.fail(d.id,pS(u),gp(u));return{result:u,operation:y}}catch(u){throw c.fail(d.id,u instanceof Error?u.message:String(u),{ok:!1,threw:!0}),u}}function pS(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function gp(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",n=typeof t.stderr==="string"?t.stderr:"",i={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(n)};if(typeof t.operation==="string")i.operation=t.operation;if(typeof t.error==="string")i.error=t.error;return Oe(i)}var vp=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],mS=new Map(vp.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function bp(e){return mS.get(e)}function U_(e,t){return vp.filter((r)=>r.modes.includes(e)&&(!t||!r.adminOnly))}import Qr from"node:process";import{existsSync as gS}from"node:fs";import{join as fS}from"node:path";async function J_(e){let t=Date.now(),r=e.sourceDir??"dist";if(!gS(fS(r,"index.html")))return mc(t,`${r}/ has no index.html — build first.`);if(!Qr.env.AWS_ACCESS_KEY_ID||!Qr.env.AWS_SECRET_ACCESS_KEY)return mc(t,"Missing AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY in env.");let n=hS(e.dnsProvider);if("error"in n)return mc(t,n.error);let i=await Sp({siteName:e.siteName,region:e.region??"us-east-1",domain:e.domain,bucket:e.bucket,stackName:e.stackName,certificateArn:e.certificateArn,defaultRootObject:e.defaultRootObject??"index.html",errorDocument:e.errorDocument??"404.html",cacheControl:e.cacheControl??"max-age=3600, public",sourceDir:r,cleanBucket:e.cleanBucket??!1,singlePageApp:e.singlePageApp??!1,dnsProvider:n,tags:{ManagedBy:"ts-cloud",Application:e.siteName,...e.tags},onProgress:e.onProgress});return{success:!!i.success,domain:i.domain,url:i.domain?`https://${i.domain}`:i.distributionDomain?`https://${i.distributionDomain}`:void 0,bucket:i.bucket,distributionId:i.distributionId,distributionDomain:i.distributionDomain,certificateArn:i.certificateArn,filesUploaded:i.filesUploaded,filesSkipped:i.filesSkipped,message:i.message,durationMs:Date.now()-t}}function hS(e){let t=typeof e==="string"?{provider:e}:e??{provider:"porkbun"};if(t.provider==="porkbun"){let r=t,n=r?.apiKey??Qr.env.PORKBUN_API_KEY,i=r?.secretKey??Qr.env.PORKBUN_SECRET_KEY??Qr.env.PORKBUN_SECRET_API_KEY;if(!n||!i)return{error:"Missing PORKBUN_API_KEY / PORKBUN_SECRET_KEY in env."};return{provider:"porkbun",apiKey:n,secretKey:i}}if(t.provider==="godaddy"){let r=t,n=r?.apiKey??Qr.env.GODADDY_API_KEY,i=r?.secretKey??Qr.env.GODADDY_API_SECRET,o=r?.environment??Qr.env.GODADDY_ENVIRONMENT;if(!n||!i)return{error:"Missing GODADDY_API_KEY / GODADDY_API_SECRET in env."};return{provider:"godaddy",apiKey:n,apiSecret:i,environment:o}}return{error:`Unsupported DNS provider: ${t.provider}`}}function mc(e,t){return{success:!1,message:t,durationMs:Date.now()-e}}import{createHash as yS}from"node:crypto";var vS=`let coldStart = true
|
|
2
2
|
const initializedAt = new Date().toISOString()
|
|
3
3
|
export const handler = async (event) => {
|
|
4
4
|
const currentColdStart = coldStart
|