@stacksjs/ts-cloud 0.16.82 → 0.16.83

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.
Files changed (104) hide show
  1. package/dist/bin/chunk-1gzxerk9.js +1 -0
  2. package/dist/bin/chunk-1nnt30xt.js +1 -0
  3. package/dist/bin/{chunk-33xqndrp.js → chunk-3x9rma7g.js} +1 -1
  4. package/dist/bin/chunk-4kt2sgqk.js +1 -0
  5. package/dist/bin/{chunk-sacx9p6f.js → chunk-5xvvxh1f.js} +4 -4
  6. package/dist/bin/{chunk-wm0rq725.js → chunk-7477zgt9.js} +1 -1
  7. package/dist/bin/{chunk-w9jfrf3v.js → chunk-859pmy2r.js} +8 -8
  8. package/dist/bin/{chunk-6ybjfjbc.js → chunk-8dzqjsz1.js} +1 -1
  9. package/dist/bin/{chunk-3wvpgb8m.js → chunk-8erhr0vh.js} +1 -1
  10. package/dist/bin/{chunk-9gp8p8hv.js → chunk-9p6hkb64.js} +1 -1
  11. package/dist/bin/{chunk-5hmrqjmq.js → chunk-b61yq5rn.js} +1 -1
  12. package/dist/bin/{chunk-20rfyk4x.js → chunk-c4krzg7x.js} +1 -1
  13. package/dist/bin/{chunk-ssnvdxh4.js → chunk-eqw1dk00.js} +1 -1
  14. package/dist/bin/{chunk-462swbg5.js → chunk-f1jkvaxm.js} +1 -1
  15. package/dist/bin/{chunk-nzg624aj.js → chunk-hkgbbph1.js} +1 -1
  16. package/dist/bin/{chunk-zg8nnq7k.js → chunk-kvwm9z1r.js} +1 -1
  17. package/dist/bin/{chunk-jx062xpq.js → chunk-mhmvr5w3.js} +1 -1
  18. package/dist/bin/{chunk-gy29teqh.js → chunk-msvg10yf.js} +1 -1
  19. package/dist/bin/chunk-q82s4yzg.js +1 -0
  20. package/dist/bin/{chunk-y9qdpwa6.js → chunk-rpsnnr53.js} +1 -1
  21. package/dist/bin/{chunk-cxf9pmmw.js → chunk-sbm0ft8c.js} +1 -1
  22. package/dist/bin/{chunk-zn2efqcr.js → chunk-sge03gvm.js} +4 -4
  23. package/dist/bin/{chunk-7848wre2.js → chunk-vr9jcw65.js} +1 -1
  24. package/dist/bin/{chunk-d0m01m6d.js → chunk-yd2vnd4y.js} +1 -1
  25. package/dist/bin/{chunk-k9s81q0g.js → chunk-ydbvafmk.js} +1 -1
  26. package/dist/bin/cli.js +16 -16
  27. package/dist/bin/dashboard-server.js +1 -1
  28. package/dist/{chunk-3wh3hsvp.js → chunk-0f23y8ba.js} +1 -1
  29. package/dist/chunk-2ntc2qz2.js +1 -0
  30. package/dist/{chunk-9w8qtr4p.js → chunk-8drf81qf.js} +1 -1
  31. package/dist/{chunk-n5qbdsbj.js → chunk-9nzmfpwt.js} +48 -48
  32. package/dist/{chunk-cf274f07.js → chunk-bhbv9qqn.js} +1 -1
  33. package/dist/{chunk-k8xv271s.js → chunk-j0tv31q2.js} +2 -2
  34. package/dist/{chunk-1h95atas.js → chunk-kcb203be.js} +1 -1
  35. package/dist/{chunk-5rds38z9.js → chunk-q61qcpp4.js} +53 -53
  36. package/dist/{chunk-eyc2tvze.js → chunk-rq650jaz.js} +1 -1
  37. package/dist/{chunk-dh5m9b05.js → chunk-xyhh44eq.js} +1 -1
  38. package/dist/deploy/index.js +1 -1
  39. package/dist/drivers/index.js +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/mail/index.js +1 -1
  42. package/dist/operations/index.js +1 -1
  43. package/dist/protection/index.js +1 -1
  44. package/dist/spend/index.js +1 -1
  45. package/dist/ui/404.html +1 -1
  46. package/dist/ui/accept-invitation.html +1 -1
  47. package/dist/ui/access-denied.html +1 -1
  48. package/dist/ui/account/automation.html +6 -6
  49. package/dist/ui/account/security.html +2 -2
  50. package/dist/ui/applications/compose.html +6 -6
  51. package/dist/ui/applications/new.html +2 -2
  52. package/dist/ui/data/backups.html +5 -5
  53. package/dist/ui/data/services.html +6 -6
  54. package/dist/ui/data/volumes.html +6 -6
  55. package/dist/ui/index.html +6 -6
  56. package/dist/ui/infrastructure/topology.html +6 -6
  57. package/dist/ui/integrations.html +1 -1
  58. package/dist/ui/operations/alerts.html +6 -6
  59. package/dist/ui/operations/configuration.html +5 -5
  60. package/dist/ui/operations/jobs.html +5 -5
  61. package/dist/ui/operations/maintenance.html +5 -5
  62. package/dist/ui/operations/observability.html +6 -6
  63. package/dist/ui/operations/previews.html +6 -6
  64. package/dist/ui/operations/queue.html +5 -5
  65. package/dist/ui/operations/regions.html +5 -5
  66. package/dist/ui/operations/releases.html +6 -6
  67. package/dist/ui/operations/spend.html +6 -6
  68. package/dist/ui/operations/workloads.html +5 -5
  69. package/dist/ui/security.html +2 -2
  70. package/dist/ui/server/actions.html +6 -6
  71. package/dist/ui/server/activity.html +1 -1
  72. package/dist/ui/server/capacity.html +6 -6
  73. package/dist/ui/server/database.html +6 -6
  74. package/dist/ui/server/deployments.html +6 -6
  75. package/dist/ui/server/diagnostics.html +2 -2
  76. package/dist/ui/server/firewall.html +6 -6
  77. package/dist/ui/server/fleet.html +6 -6
  78. package/dist/ui/server/logs.html +6 -6
  79. package/dist/ui/server/metrics.html +6 -6
  80. package/dist/ui/server/security.html +2 -2
  81. package/dist/ui/server/services.html +1 -1
  82. package/dist/ui/server/sites.html +6 -6
  83. package/dist/ui/server/ssh-keys.html +6 -6
  84. package/dist/ui/server/team.html +6 -6
  85. package/dist/ui/server/terminal.html +2 -2
  86. package/dist/ui/serverless/alarms.html +6 -6
  87. package/dist/ui/serverless/assets.html +2 -2
  88. package/dist/ui/serverless/cost.html +2 -2
  89. package/dist/ui/serverless/data.html +6 -6
  90. package/dist/ui/serverless/deployments.html +2 -2
  91. package/dist/ui/serverless/firewall.html +1 -1
  92. package/dist/ui/serverless/functions.html +6 -6
  93. package/dist/ui/serverless/logs.html +6 -6
  94. package/dist/ui/serverless/metrics.html +2 -2
  95. package/dist/ui/serverless/queues.html +6 -6
  96. package/dist/ui/serverless/secrets.html +6 -6
  97. package/dist/ui/serverless/traces.html +6 -6
  98. package/dist/ui/serverless.html +6 -6
  99. package/package.json +3 -3
  100. package/dist/bin/chunk-4c4q96vm.js +0 -1
  101. package/dist/bin/chunk-9nen8018.js +0 -1
  102. package/dist/bin/chunk-abt0636a.js +0 -1
  103. package/dist/bin/chunk-tpy9t3cv.js +0 -1
  104. package/dist/chunk-5v2wpf1k.js +0 -1
package/dist/bin/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import{C,Kt,n,r,a,_r,e,u,i,s,P,d,Ko,c,vn,Ee,ia,oa,sa,aa,f}from"./chunk-qpasspad.js";import{ga,H,Fr,w,U,Qo,l,o,T,ha,ya,ba,$e,He,st,Zo,An,ji,Rn,es,Ta,Ea,wa,Aa,Ia,j,b,M,at,N,ye,rs,qe,Yt,Vi,Ie,ns,zi,Zt,Nt,Pa,Da}from"./chunk-sacx9p6f.js";import"./chunk-8rkfwgb4.js";import{Me,_,$n,y,Ln,Zi,Mn,us,qr,lt,xe,Un,Bn,jn,Vn,zn,Hn,Gn,qn,oe,sr,ar,Wn,Wr,Kn,Jn,Xn,Qn,Yn,Zn,ei,ti,dt,cr,lr,$t,Kr,dr,ur,eo,Lt,ri,de,ni,ii,oi,Jr,Xr,si,Qr,pr,mr,ut,Mt,Ut,Yr,ue,ai,gc,fc,gr,hc,G,to,We,pt,mt,ci,Zr,li,en,di,ui,tn,ps,pe,ve,Ue,Ce,pi,fr}from"./chunk-zn2efqcr.js";import{p,la}from"./chunk-btrxye8p.js";import{ce,h,Br}from"./chunk-ssnvdxh4.js";import{Or,Pt,$r,Lr,Mr,Ur,Cn}from"./chunk-d0m01m6d.js";import{S,Bt,mi,gs,hr,yc,bc,Sc,gi,fi,rn,Ft,nn,gt,ft,Ke,Fe,Je,ht,yr,je,Xe,hi,yi,Qe,on,sn,io,so,vr,jt,yt,Vt,ee,uo,vi,Ci,Rs}from"./chunk-462swbg5.js";import{ot,Gt,Dr,Qs,Ys,kr,he,Mi,Nr,Lo,Mo,Uo,Bo,Fo,jo,K,qt,B,Ui}from"./chunk-qmwqntnx.js";import{W,A,Io,Fs,js,Wc,Kc,gn,wt,_i}from"./chunk-w9jfrf3v.js";import{v}from"./chunk-yf2drw7r.js";import{Q}from"./chunk-cgyk48s5.js";import{It,g}from"./chunk-1wgyq50e.js";import{Ze,Ns,me,mo,Ei,go,fo,cn,ho,yo,Te,te,et,_e,ln,St,Oe,Cr,dn,tt,rt,Tr,un,wi,Ai,ge,vt,Ri,wr,Ar,Rr,pn,Ir,O,So,vo,zc,Co,xs,_s,Os,$s,Ct,Ls,To,Eo,wo}from"./chunk-33xqndrp.js";import"./chunk-20rfyk4x.js";import{D}from"./chunk-19mhwmfp.js";import{fe}from"./chunk-zfn3a9sx.js";import{J,Rt,qo}from"./chunk-nzg624aj.js";import{ae,q,jc,Vc,Ye}from"./chunk-3wvpgb8m.js";import{ir,_n,or,Qi,On,ds}from"./chunk-w40r35vn.js";import"./chunk-gy29teqh.js";import{E}from"./chunk-jqs2ywj2.js";import{bt}from"./chunk-t0r1rdj2.js";import{re,we}from"./chunk-08sws53b.js";import{V}from"./chunk-89v3ec9n.js";import"./chunk-zn9wmqd1.js";import"./chunk-35325988.js";import{Yi}from"./chunk-f7jzs1h1.js";import"./chunk-cxf9pmmw.js";import"./chunk-9gp8p8hv.js";import{Di}from"./chunk-83tt2t15.js";import{Pr}from"./chunk-b1cb27m8.js";import{At}from"./chunk-z9g7fa1w.js";import{F}from"./chunk-69mejej3.js";import{x}from"./chunk-bkx2kapc.js";import{existsSync as _u}from"node:fs";import Oa from"node:fs/promises";import Vl from"node:os";import La from"node:path";import Xi from"node:process";import{EventEmitter as Mu}from"node:events";import Li from"node:process";import ql from"node:process";import Ba from"node:process";import Ts from"node:process";import Jo from"node:process";import Jl from"node:tty";import Pm,{stdin as sy,stdout as ay}from"node:process";class Yl{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let R=Vl.homedir(),t=La.join(R,".config","clapp");this.configPath=La.join(t,"telemetry.json")}async isEnabled(){if(Xi.env.DO_NOT_TRACK==="1"||Xi.env.DO_NOT_TRACK==="true")return!1;if(Xi.env.NO_TELEMETRY==="1"||Xi.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,t){if(!await this.isEnabled())return;let k={event:R,...t,timestamp:Date.now(),platform:Vl.platform(),nodeVersion:Xi.version};if(this.events.push(k),this.events.length>=10)await this.send()}async trackCommand(R,t){await this.track("command",{command:R,duration:t})}async trackError(R,t){await this.track("error",{error:R,command:t})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let t=await this.loadConfig();return t.lastSent=Date.now(),await this.saveConfig(t),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let t=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(t),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(R){return new Promise((t)=>setTimeout(t,R))}async status(){let R=await this.loadConfig();return{enabled:R.enabled,doNotTrack:Xi.env.DO_NOT_TRACK==="1"||Xi.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:R.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(_u(this.configPath)){let R=await Oa.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 t=La.dirname(this.configPath);await Oa.mkdir(t,{recursive:!0}),await Oa.writeFile(this.configPath,JSON.stringify(R,null,2),"utf-8")}catch{}}generateUserId(){let R=Math.random().toString(36).substring(2,15),t=Date.now().toString(36);return`${R}-${t}`}}var Gh=new Yl;function ja(R){return R.replace(/[<[].+/,"").trim()}function zu(R){let t=/<([^>]+)>/g,m=/\[([^\]]+)\]/g,k=[],I=(Y)=>{let Z=!1,X=Y[1];if(X.startsWith("..."))X=X.slice(3),Z=!0;return{required:Y[0].startsWith("<"),value:X,variadic:Z}},L;while(L=t.exec(R))k.push(I(L));let z;while(z=m.exec(R))k.push(I(z));return k}function Uu(R){let t={alias:{},boolean:[]};for(let[m,k]of R.entries()){if(k.names.length>1)t.alias[k.names[0]]=k.names.slice(1);if(k.isBoolean)if(k.negated){if(!R.some((L,z)=>z!==m&&L.names.some((Y)=>k.names.includes(Y))&&typeof L.required==="boolean"))t.boolean.push(k.names[0])}else t.boolean.push(k.names[0])}return t}function Hl(R){return R.reduce((t,m)=>t.length>=m.length?t:m,"")}function Fa(R,t){return R.length>=t?R:`${R}${" ".repeat(t-R.length)}`}function Es(R){return R.replace(/([a-z])-([a-z])/g,(t,m,k)=>m+k.toUpperCase())}function Wu(R,t,m){let k=0,I=t.length,L=R,z;for(;k<I;++k)z=L[t[k]],L=L[t[k]]=k===I-1?m:z!=null?z:!!~t[k+1].indexOf(".")||!(+t[k+1]>-1)?{}:[]}function Vu(R,t){for(let m of Object.keys(t)){let k=t[m];if(k.shouldTransform){if(R[m]=Array.prototype.concat.call([],R[m]),typeof k.transformFunction==="function")R[m]=R[m].map(k.transformFunction)}}}function qu(R){let t=/([^\\/]+)$/.exec(R);return t?t[1]:""}function Yo(R){return R.split(".").map((t,m)=>m===0?Es(t):t).join(".")}class Xo extends Error{exitCode=2;isUsageError=!0;usage;constructor(R,t){super(R);if(this.name=this.constructor.name,t!==void 0)this.usage=t;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(R).stack}format(R=!1){if(R&&this.stack)return`${this.message}
2
+ import{C,Kt,n,r,a,_r,e,u,i,s,P,d,Ko,c,vn,Ee,ia,oa,sa,aa,f}from"./chunk-qpasspad.js";import{ga,H,Fr,w,U,Qo,l,o,T,ha,ya,ba,$e,He,st,Zo,An,ji,Rn,es,Ta,Ea,wa,Aa,Ia,j,b,M,at,N,ye,rs,qe,Yt,Vi,Ie,ns,zi,Zt,Nt,Pa,Da}from"./chunk-5xvvxh1f.js";import"./chunk-8rkfwgb4.js";import{Me,_,$n,y,Ln,Zi,Mn,us,qr,lt,xe,Un,Bn,jn,Vn,zn,Hn,Gn,qn,oe,sr,ar,Wn,Wr,Kn,Jn,Xn,Qn,Yn,Zn,ei,ti,dt,cr,lr,$t,Kr,dr,ur,eo,Lt,ri,de,ni,ii,oi,Jr,Xr,si,Qr,pr,mr,ut,Mt,Ut,Yr,ue,ai,gc,fc,gr,hc,G,to,We,pt,mt,ci,Zr,li,en,di,ui,tn,ps,pe,ve,Ue,Ce,pi,fr}from"./chunk-sge03gvm.js";import{p,la}from"./chunk-btrxye8p.js";import{ce,h,Br}from"./chunk-eqw1dk00.js";import{Or,Pt,$r,Lr,Mr,Ur,Cn}from"./chunk-yd2vnd4y.js";import{S,Bt,mi,gs,hr,yc,bc,Sc,gi,fi,rn,Ft,nn,gt,ft,Ke,Fe,Je,ht,yr,je,Xe,hi,yi,Qe,on,sn,io,so,vr,jt,yt,Vt,ee,uo,vi,Ci,Rs}from"./chunk-f1jkvaxm.js";import{ot,Gt,Dr,Qs,Ys,kr,he,Mi,Nr,Lo,Mo,Uo,Bo,Fo,jo,K,qt,B,Ui}from"./chunk-qmwqntnx.js";import{W,A,Io,Fs,js,Wc,Kc,gn,wt,_i}from"./chunk-859pmy2r.js";import{v}from"./chunk-yf2drw7r.js";import{Q}from"./chunk-cgyk48s5.js";import{It,g}from"./chunk-1wgyq50e.js";import{Ze,Ns,me,mo,Ei,go,fo,cn,ho,yo,Te,te,et,_e,ln,St,Oe,Cr,dn,tt,rt,Tr,un,wi,Ai,ge,vt,Ri,wr,Ar,Rr,pn,Ir,O,So,vo,zc,Co,xs,_s,Os,$s,Ct,Ls,To,Eo,wo}from"./chunk-3x9rma7g.js";import"./chunk-c4krzg7x.js";import{D}from"./chunk-19mhwmfp.js";import{fe}from"./chunk-zfn3a9sx.js";import{J,Rt,qo}from"./chunk-hkgbbph1.js";import{ae,q,jc,Vc,Ye}from"./chunk-8erhr0vh.js";import{ir,_n,or,Qi,On,ds}from"./chunk-w40r35vn.js";import"./chunk-msvg10yf.js";import{E}from"./chunk-jqs2ywj2.js";import{bt}from"./chunk-t0r1rdj2.js";import{re,we}from"./chunk-08sws53b.js";import{V}from"./chunk-89v3ec9n.js";import"./chunk-zn9wmqd1.js";import"./chunk-35325988.js";import{Yi}from"./chunk-f7jzs1h1.js";import"./chunk-sbm0ft8c.js";import"./chunk-9p6hkb64.js";import{Di}from"./chunk-83tt2t15.js";import{Pr}from"./chunk-b1cb27m8.js";import{At}from"./chunk-z9g7fa1w.js";import{F}from"./chunk-69mejej3.js";import{x}from"./chunk-bkx2kapc.js";import{existsSync as _u}from"node:fs";import Oa from"node:fs/promises";import Vl from"node:os";import La from"node:path";import Xi from"node:process";import{EventEmitter as Mu}from"node:events";import Li from"node:process";import ql from"node:process";import Ba from"node:process";import Ts from"node:process";import Jo from"node:process";import Jl from"node:tty";import Pm,{stdin as sy,stdout as ay}from"node:process";class Yl{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let R=Vl.homedir(),t=La.join(R,".config","clapp");this.configPath=La.join(t,"telemetry.json")}async isEnabled(){if(Xi.env.DO_NOT_TRACK==="1"||Xi.env.DO_NOT_TRACK==="true")return!1;if(Xi.env.NO_TELEMETRY==="1"||Xi.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,t){if(!await this.isEnabled())return;let k={event:R,...t,timestamp:Date.now(),platform:Vl.platform(),nodeVersion:Xi.version};if(this.events.push(k),this.events.length>=10)await this.send()}async trackCommand(R,t){await this.track("command",{command:R,duration:t})}async trackError(R,t){await this.track("error",{error:R,command:t})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let t=await this.loadConfig();return t.lastSent=Date.now(),await this.saveConfig(t),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let t=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(t),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(R){return new Promise((t)=>setTimeout(t,R))}async status(){let R=await this.loadConfig();return{enabled:R.enabled,doNotTrack:Xi.env.DO_NOT_TRACK==="1"||Xi.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:R.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(_u(this.configPath)){let R=await Oa.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 t=La.dirname(this.configPath);await Oa.mkdir(t,{recursive:!0}),await Oa.writeFile(this.configPath,JSON.stringify(R,null,2),"utf-8")}catch{}}generateUserId(){let R=Math.random().toString(36).substring(2,15),t=Date.now().toString(36);return`${R}-${t}`}}var Gh=new Yl;function ja(R){return R.replace(/[<[].+/,"").trim()}function zu(R){let t=/<([^>]+)>/g,m=/\[([^\]]+)\]/g,k=[],I=(Y)=>{let Z=!1,X=Y[1];if(X.startsWith("..."))X=X.slice(3),Z=!0;return{required:Y[0].startsWith("<"),value:X,variadic:Z}},L;while(L=t.exec(R))k.push(I(L));let z;while(z=m.exec(R))k.push(I(z));return k}function Uu(R){let t={alias:{},boolean:[]};for(let[m,k]of R.entries()){if(k.names.length>1)t.alias[k.names[0]]=k.names.slice(1);if(k.isBoolean)if(k.negated){if(!R.some((L,z)=>z!==m&&L.names.some((Y)=>k.names.includes(Y))&&typeof L.required==="boolean"))t.boolean.push(k.names[0])}else t.boolean.push(k.names[0])}return t}function Hl(R){return R.reduce((t,m)=>t.length>=m.length?t:m,"")}function Fa(R,t){return R.length>=t?R:`${R}${" ".repeat(t-R.length)}`}function Es(R){return R.replace(/([a-z])-([a-z])/g,(t,m,k)=>m+k.toUpperCase())}function Wu(R,t,m){let k=0,I=t.length,L=R,z;for(;k<I;++k)z=L[t[k]],L=L[t[k]]=k===I-1?m:z!=null?z:!!~t[k+1].indexOf(".")||!(+t[k+1]>-1)?{}:[]}function Vu(R,t){for(let m of Object.keys(t)){let k=t[m];if(k.shouldTransform){if(R[m]=Array.prototype.concat.call([],R[m]),typeof k.transformFunction==="function")R[m]=R[m].map(k.transformFunction)}}}function qu(R){let t=/([^\\/]+)$/.exec(R);return t?t[1]:""}function Yo(R){return R.split(".").map((t,m)=>m===0?Es(t):t).join(".")}class Xo extends Error{exitCode=2;isUsageError=!0;usage;constructor(R,t){super(R);if(this.name=this.constructor.name,t!==void 0)this.usage=t;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(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 Hu(R){if(R instanceof Xo)return!0;return!!R&&typeof R==="object"&&R.name==="ClappError"&&typeof R.message==="string"}function Gu(){let{env:R}=ql,{TERM:t,TERM_PROGRAM:m}=R;if(ql.platform!=="win32")return t!=="linux";return Boolean(R.WT_SESSION)||Boolean(R.TERMINUS_SUBLIME)||R.ConEmuTask==="{cmd::Cmder}"||m==="Terminus-Sublime"||m==="vscode"||t==="xterm-256color"||t==="alacritty"||t==="rxvt-unicode"||t==="rxvt-unicode-256color"||R.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var Bs="\x1B",mn=`${Bs}[`;var Gl={to(R,t){if(!t)return`${mn}${R+1}G`;return`${mn}${t+1};${R+1}H`},move(R,t){let m="";if(R<0)m+=`${mn}${-R}D`;else if(R>0)m+=`${mn}${R}C`;if(t<0)m+=`${mn}${-t}A`;else if(t>0)m+=`${mn}${t}B`;return m},up:(R=1)=>`${mn}${R}A`,down:(R=1)=>`${mn}${R}B`,forward:(R=1)=>`${mn}${R}C`,backward:(R=1)=>`${mn}${R}D`,nextLine:(R=1)=>`${mn}E`.repeat(R),prevLine:(R=1)=>`${mn}F`.repeat(R),left:`${mn}G`,hide:`${mn}?25l`,show:`${mn}?25h`,save:`${Bs}7`,restore:`${Bs}8`};var Zh={screen:`${mn}2J`,up:(R=1)=>`${mn}1J`.repeat(R),down:(R=1)=>`${mn}J`.repeat(R),line:`${mn}2K`,lineEnd:`${mn}K`,lineStart:`${mn}1K`,lines(R){let t="";for(let m=0;m<R;m++)t+=this.line+(m<R-1?Gl.up():"");if(R)t+=Gl.left;return t}},Qh={screen:`${Bs}c`};function Ku(R,t){let m=[];for(let k=0;k<=t.length;k++)m[k]=[k];for(let k=0;k<=R.length;k++)m[0][k]=k;for(let k=1;k<=t.length;k++)for(let I=1;I<=R.length;I++)if(t.charAt(k-1)===R.charAt(I-1))m[k][I]=m[k-1][I-1];else m[k][I]=Math.min(m[k-1][I-1]+1,m[k][I-1]+1,m[k-1][I]+1);return m[t.length][R.length]}function Zl(R,t,m=2,k=3){return t.map((I)=>({cmd:I,distance:Ku(R,I)})).filter(({distance:I})=>I<=m).sort((I,L)=>I.distance-L.distance).slice(0,k).map(({cmd:I})=>I)}function Ju(R,t={}){let m={_:[]},k=t.alias||{},I=new Set(t.boolean||[]),L={};for(let Z of Object.keys(k))for(let X of k[Z])L[X]=Z;for(let Z of I)if(k[Z])for(let X of k[Z])I.add(X);function z(Z,X){if(Z===void 0)return X;if(typeof X==="boolean")return X;return Array.isArray(Z)?[...Z,X]:[Z,X]}function Y(Z,X){let ne=L[Z]||Z,ie=z(m[ne],X);if(m[ne]=ie,k[ne])for(let se of k[ne])m[se]=ie;if(L[Z]&&k[L[Z]])for(let se of k[L[Z]])m[se]=ie;m[Z]=ie}for(let Z=0;Z<R.length;Z++){let X=R[Z];if(X==="--"){m._.push(...R.slice(Z+1));break}if(X.startsWith("--")){let ne=X.indexOf("=");if(ne!==-1){let ie=Es(X.slice(2,ne)),se=X.slice(ne+1);Y(ie,se)}else{let ie=X.slice(2);if(ie.startsWith("no-")){let Ae=Es(ie.slice(3));Y(Ae,!1);continue}let se=Es(ie),be=L[se]||se;if(I.has(be)||I.has(se))Y(se,!0);else{let Ae=R[Z+1];if(Ae!==void 0&&!Ae.startsWith("-"))Y(se,Ae),Z++;else Y(se,!0)}}}else if(X.startsWith("-")&&X.length>1){let ne=X.slice(1);for(let ie=0;ie<ne.length;ie++){let se=ne[ie],be=L[se]||se;if(ie===ne.length-1&&!I.has(be)&&!I.has(se)){let Ae=R[Z+1];if(Ae!==void 0&&!Ae.startsWith("-"))Y(se,Ae),Z++;else Y(se,!0)}else Y(se,!0)}}else m._.push(X)}return m}class Ql{rawName;description;name;names;isBoolean;required;config;negated;constructor(R,t,m){if(this.rawName=R,this.description=t,this.config=Object.assign({},m),R=R.replace(/\.\*/g,""),this.negated=!1,this.names=ja(R).split(",").map((k)=>{let I=k.trim().replace(/^-{1,2}/,"");if(I.startsWith("no-"))this.negated=!0,I=I.replace(/^no-/,"");return Yo(I)}).sort((k,I)=>k.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 ey=Ba.argv,Yu=`${Ba.platform}-${Ba.arch} bun-v${typeof Bun<"u"?Bun.version:"unknown"}`,Kl=Ts.argv,Zu=`${Ts.platform}-${Ts.arch} node-${Ts.version}`;class _a{rawName;description;config;cli;options;aliasNames;name;namespace;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;beforeHooks;afterHooks;middleware;constructor(R,t,m,k){this.rawName=R,this.description=t,this.config=m,this.cli=k,this.options=[],this.aliasNames=[],this.name=ja(R);let I=ja(R),L=I.indexOf(":");if(L>0)this.namespace=I.substring(0,L),this.name=I.substring(L+1);if(this.args=zu(R),this.examples=[],this.beforeHooks=[],this.afterHooks=[],this.middleware=[],!m)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,t="-v, --version"){return this.versionNumber=R,this.option(t,"Display version number"),this}example(R){return this.examples.push(R),this}option(R,t,m){let k=new Ql(R,t,m);return this.options.push(k),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 Ma}get displayName(){return this.namespace?`${this.namespace}:${this.name}`:this.name}hasOption(R){let t=Yo(R.split(".")[0]);return!!this.options.find((m)=>m.names.some((k)=>Yo(k)===t))}outputHelp(){let{name:R,commands:t}=this.cli,{versionNumber:m,options:k,helpCallback:I}=this.cli.globalCommand,L=[{body:`${R}${m?`/${m}`:""}`}];if(L.push({title:"Usage",body:` $ ${R} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let X=Hl(t.map((Ae)=>Ae.rawName)),ne=new Map,ie=[];for(let Ae of t)if(Ae.namespace){if(!ne.has(Ae.namespace))ne.set(Ae.namespace,[]);ne.get(Ae.namespace).push(Ae)}else ie.push(Ae);let se="";if(ie.sort((Ae,le)=>Ae.rawName<le.rawName?-1:Ae.rawName>le.rawName?1:0),ie.length>0)se+=ie.map((Ae)=>` ${Fa(Ae.rawName,X.length)} ${Ae.description}`).join(`
@@ -28,7 +28,7 @@ Received ${m}, cleaning up...`),R)try{await R()}catch(k){console.error("Error du
28
28
  `)),this.enableDidYouMean){let t=[];for(let k of this.commands){if(k.displayName)t.push(k.displayName);if(k.aliasNames)t.push(...k.aliasNames)}let m=Zl(R,t);if(m.length>0)console.log(Go.yellow("Did you mean one of these?")),m.forEach((k)=>console.log(` ${Go.dim("•")} ${this.name} ${k}`)),console.log("")}console.log(Go.dim("Run"),`${this.name} --help`,Go.dim("to see all available commands")),Li.exit(1)}async parse(R=Kl,t={}){let{run:m=!0,exitOnError:k=!1}=t;if(k)try{return await this.parse(R,{run:m})}catch(Z){throw this.handleUsageError(Z),Z}if(this.rawArgs=R,!this.name)this.name=R[1]?qu(R[1]):"cli";let I=!0,L=R.slice(2),z=L[0];if(z&&!z.startsWith("-")){for(let Z of this.commands)if(Z.isMatched(z)){let X=this.mri(L,Z);I=!1;let ne={...X,args:X.args.slice(1)};this.setParsedInfo(ne,Z,z),this.emit(`command:${z}`,Z);break}if(I){let Z=L[1];if(Z&&!Z.startsWith("-")){let X=`${z}:${Z}`;for(let ne of this.commands)if(ne.isMatched(X)){let ie=this.mri(L,ne);I=!1;let se={...ie,args:ie.args.slice(2)};this.setParsedInfo(se,ne,X),this.emit(`command:${X}`,ne);break}}}}if(I){for(let Z of this.commands)if(Z.name===""){I=!1;let X=this.mri(L,Z);this.setParsedInfo(X,Z),this.emit("command:!",Z);break}}if(I){let Z=this.mri(R.slice(2));this.setParsedInfo(Z)}if(this.options.verbose)this.isVerbose=!0;if(this.options.quiet)this.isQuiet=!0;if(this.options.debug)this.isDebug=!0;if(this.options.noInteraction||this.options.interaction===!1)this.isNoInteraction=!0;if(this.options.env)this.environment=String(this.options.env);if(this.options.dryRun)this.isDryRun=!0;if(this.options.force)this.isForce=!0;if(this.options.noEmoji||this.options.emoji===!1)this.useEmoji=!1;if(this.options.theme)this.theme=String(this.options.theme);if(this.options.noCache||this.options.cache===!1)this.isNoCache=!0;if(this.options.help&&this.showHelpOnExit)this.outputHelp(),m=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),m=!1,this.unsetMatchedCommand();let Y={args:this.args,options:this.options};if(m)await this.runMatchedCommand();if(!this.matchedCommand&&this.args[0]){if(this.emit("command:*"),!(this.listenerCount("command:*")>0))this.showCommandNotFound(this.args[0])}return Y}mri(R,t){let m=[...this.globalCommand.options,...t?t.options:[]],k=Uu(m),I=[],L=R.indexOf("--");if(L>-1)I=R.slice(L+1),R=R.slice(0,L);let z=Ju(R,k),Y={_:z._};for(let se of Object.keys(z))if(se!=="_")Y[Yo(se)]=z[se];let Z=Y._,X={"--":I},ne=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,ie=Object.create(null);for(let se of m){if(!ne&&se.config.default!==void 0)for(let be of se.names)X[be]=se.config.default;if(Array.isArray(se.config.type)){if(ie[se.name]===void 0)ie[se.name]={shouldTransform:!0,transformFunction:se.config.type[0]}}}for(let se of Object.keys(Y))if(se!=="_"){let be=se.split(".");Wu(X,be,Y[se]),Vu(X,ie)}return{args:Z,options:X}}async run(R=Kl){return this.parse(R,{run:!0,exitOnError:!0})}handleUsageError(R){if(!Hu(R)||R.isUsageError===!1)return;let t=R.message||"command-line error",m=this.name?`${this.name}: `:"",k=/--help/.test(t)?"":R.usage?`
29
29
  Usage: ${R.usage}`:`
30
30
  Run \`${this.name??"cli"} --help\` for usage.`;Li.stderr.write(`${m}${t}${k}
31
- `),Li.exit(R.exitCode??2)}async runMatchedCommand(){let{args:R,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let k=[];m.args.forEach((Y,Z)=>{if(Y.variadic)k.push(R.slice(Z));else k.push(R[Z])}),k.push(t);let I={command:m,args:k,options:t};for(let Y of m.beforeHooks)await Y(I);let L,z=async()=>{let Y=m.commandAction.apply(this,k);if(Y instanceof Promise)L=await Y;else L=Y;return L};if(m.middleware.length>0){let Y=0,Z=async()=>{if(Y<m.middleware.length){let X=m.middleware[Y++];await X({...I,next:Z})}else await z()};await Z()}else await z();for(let Y of m.afterHooks)await Y(I);return L}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return Li.removeAllListeners("SIGINT"),Li.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 Xl{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 t=this.cache.get(R);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(R),this.misses++;return}return this.hits++,t.value}set(R,t,m=5000){if(!this.enabled)return;this.cache.set(R,{value:t,timestamp:Date.now(),ttl:m})}has(R){if(!this.enabled)return!1;let t=this.cache.get(R);if(!t)return!1;if(Date.now()-t.timestamp>t.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[t,m]of this.cache.entries())if(R-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var ny=new Xl;function tm(){if("FORCE_COLOR"in Jo.env)return Jo.env.FORCE_COLOR!=="0";if("NO_COLOR"in Jo.env||Jo.env.TERM==="dumb")return!1;if(Jo.platform==="win32")return!0;return Jl.isatty(1)&&Jl.isatty(2)}var ed=tm();function an(R,t){if(!ed)return(m)=>m;return(m)=>R+m+t}var nm=an("\x1B[0m","\x1B[0m"),rm=an("\x1B[31m","\x1B[39m"),im=an("\x1B[32m","\x1B[39m"),om=an("\x1B[33m","\x1B[39m"),sm=an("\x1B[34m","\x1B[39m"),am=an("\x1B[35m","\x1B[39m"),cm=an("\x1B[36m","\x1B[39m"),lm=an("\x1B[37m","\x1B[39m"),dm=an("\x1B[90m","\x1B[39m"),um=an("\x1B[1m","\x1B[22m"),mm=an("\x1B[3m","\x1B[23m"),pm=an("\x1B[4m","\x1B[24m"),fm=an("\x1B[2m","\x1B[22m"),gm=an("\x1B[7m","\x1B[27m"),hm=an("\x1B[8m","\x1B[28m"),ym=an("\x1B[9m","\x1B[29m"),vm=an("\x1B[41m","\x1B[49m"),bm=an("\x1B[42m","\x1B[49m"),wm=an("\x1B[43m","\x1B[49m"),Sm=an("\x1B[44m","\x1B[49m"),Cm=an("\x1B[45m","\x1B[49m"),$m=an("\x1B[46m","\x1B[49m"),km=an("\x1B[47m","\x1B[49m"),Am=ed,Rm={reset:nm,red:rm,green:im,yellow:om,blue:sm,magenta:am,cyan:cm,white:lm,gray:dm,bold:um,italic:mm,underline:pm,dim:fm,inverse:gm,hidden:hm,strikethrough:ym,bgRed:vm,bgGreen:bm,bgYellow:wm,bgBlue:Sm,bgMagenta:Cm,bgCyan:$m,bgWhite:km,isColorSupported:Am},Im=Rm,xm=["up","down","left","right","space","enter","cancel"],cy={actions:new Set(xm),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ly=Pm.platform.startsWith("win"),dy=Symbol("clapp:cancel");var Dm=Gu();var Xt=(R,t)=>Dm?R:t,uy=Xt("◆","*"),my=Xt("■","x"),py=Xt("▲","x"),fy=Xt("◇","o"),gy=Xt("┌","T"),Em=Xt("│","|"),hy=Xt("└","—"),yy=Xt("●",">"),vy=Xt("○"," "),by=Xt("◻","[•]"),wy=Xt("◼","[+]"),Sy=Xt("◻","[ ]"),Cy=Xt("▪","•"),$y=Xt("─","-"),ky=Xt("╮","+"),Ay=Xt("├","+"),Ry=Xt("╯","+"),Iy=Xt("●","•"),Py=Xt("◆","*"),xy=Xt("▲","!"),Dy=Xt("■","x");var Ey={light:Xt("─","-"),heavy:Xt("━","="),block:Xt("█","#")};function Tm(){return`${Im.gray(Em)} `}var Ty=Tm();var Ua="0.16.82";function td(R,t,m=process.env){let k=t?.options.find((z)=>z.name==="profile");if((!k||/\baws\b/i.test(k.description))&&typeof R.profile==="string"&&R.profile)m.AWS_PROFILE=R.profile,delete m.AWS_ACCESS_KEY_ID,delete m.AWS_SECRET_ACCESS_KEY,delete m.AWS_SESSION_TOKEN;if(!t?.options.some((z)=>z.name==="region")&&typeof R.region==="string"&&R.region)m.AWS_REGION=R.region,m.AWS_DEFAULT_REGION=R.region}import{existsSync as Wa}from"node:fs";import{mkdir as Om,writeFile as nd}from"node:fs/promises";function Va(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(t)=>{if(i("Initializing ts-cloud Project"),Wa("cloud.config.ts")){if(!await d("cloud.config.ts already exists. Overwrite?",!1)){e("Initialization cancelled");return}}let m=t?.name||await P("Project name","my-app"),k=t?.mode||await Ko("Select deployment mode",["serverless","server"]),I=t?.region||await Ko("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),L=new s("Creating configuration file...");L.start();let z=`import { defineConfig } from '@ts-cloud/core'
31
+ `),Li.exit(R.exitCode??2)}async runMatchedCommand(){let{args:R,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let k=[];m.args.forEach((Y,Z)=>{if(Y.variadic)k.push(R.slice(Z));else k.push(R[Z])}),k.push(t);let I={command:m,args:k,options:t};for(let Y of m.beforeHooks)await Y(I);let L,z=async()=>{let Y=m.commandAction.apply(this,k);if(Y instanceof Promise)L=await Y;else L=Y;return L};if(m.middleware.length>0){let Y=0,Z=async()=>{if(Y<m.middleware.length){let X=m.middleware[Y++];await X({...I,next:Z})}else await z()};await Z()}else await z();for(let Y of m.afterHooks)await Y(I);return L}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return Li.removeAllListeners("SIGINT"),Li.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 Xl{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 t=this.cache.get(R);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(R),this.misses++;return}return this.hits++,t.value}set(R,t,m=5000){if(!this.enabled)return;this.cache.set(R,{value:t,timestamp:Date.now(),ttl:m})}has(R){if(!this.enabled)return!1;let t=this.cache.get(R);if(!t)return!1;if(Date.now()-t.timestamp>t.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[t,m]of this.cache.entries())if(R-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var ny=new Xl;function tm(){if("FORCE_COLOR"in Jo.env)return Jo.env.FORCE_COLOR!=="0";if("NO_COLOR"in Jo.env||Jo.env.TERM==="dumb")return!1;if(Jo.platform==="win32")return!0;return Jl.isatty(1)&&Jl.isatty(2)}var ed=tm();function an(R,t){if(!ed)return(m)=>m;return(m)=>R+m+t}var nm=an("\x1B[0m","\x1B[0m"),rm=an("\x1B[31m","\x1B[39m"),im=an("\x1B[32m","\x1B[39m"),om=an("\x1B[33m","\x1B[39m"),sm=an("\x1B[34m","\x1B[39m"),am=an("\x1B[35m","\x1B[39m"),cm=an("\x1B[36m","\x1B[39m"),lm=an("\x1B[37m","\x1B[39m"),dm=an("\x1B[90m","\x1B[39m"),um=an("\x1B[1m","\x1B[22m"),mm=an("\x1B[3m","\x1B[23m"),pm=an("\x1B[4m","\x1B[24m"),fm=an("\x1B[2m","\x1B[22m"),gm=an("\x1B[7m","\x1B[27m"),hm=an("\x1B[8m","\x1B[28m"),ym=an("\x1B[9m","\x1B[29m"),vm=an("\x1B[41m","\x1B[49m"),bm=an("\x1B[42m","\x1B[49m"),wm=an("\x1B[43m","\x1B[49m"),Sm=an("\x1B[44m","\x1B[49m"),Cm=an("\x1B[45m","\x1B[49m"),$m=an("\x1B[46m","\x1B[49m"),km=an("\x1B[47m","\x1B[49m"),Am=ed,Rm={reset:nm,red:rm,green:im,yellow:om,blue:sm,magenta:am,cyan:cm,white:lm,gray:dm,bold:um,italic:mm,underline:pm,dim:fm,inverse:gm,hidden:hm,strikethrough:ym,bgRed:vm,bgGreen:bm,bgYellow:wm,bgBlue:Sm,bgMagenta:Cm,bgCyan:$m,bgWhite:km,isColorSupported:Am},Im=Rm,xm=["up","down","left","right","space","enter","cancel"],cy={actions:new Set(xm),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ly=Pm.platform.startsWith("win"),dy=Symbol("clapp:cancel");var Dm=Gu();var Xt=(R,t)=>Dm?R:t,uy=Xt("◆","*"),my=Xt("■","x"),py=Xt("▲","x"),fy=Xt("◇","o"),gy=Xt("┌","T"),Em=Xt("│","|"),hy=Xt("└","—"),yy=Xt("●",">"),vy=Xt("○"," "),by=Xt("◻","[•]"),wy=Xt("◼","[+]"),Sy=Xt("◻","[ ]"),Cy=Xt("▪","•"),$y=Xt("─","-"),ky=Xt("╮","+"),Ay=Xt("├","+"),Ry=Xt("╯","+"),Iy=Xt("●","•"),Py=Xt("◆","*"),xy=Xt("▲","!"),Dy=Xt("■","x");var Ey={light:Xt("─","-"),heavy:Xt("━","="),block:Xt("█","#")};function Tm(){return`${Im.gray(Em)} `}var Ty=Tm();var Ua="0.16.83";function td(R,t,m=process.env){let k=t?.options.find((z)=>z.name==="profile");if((!k||/\baws\b/i.test(k.description))&&typeof R.profile==="string"&&R.profile)m.AWS_PROFILE=R.profile,delete m.AWS_ACCESS_KEY_ID,delete m.AWS_SECRET_ACCESS_KEY,delete m.AWS_SESSION_TOKEN;if(!t?.options.some((z)=>z.name==="region")&&typeof R.region==="string"&&R.region)m.AWS_REGION=R.region,m.AWS_DEFAULT_REGION=R.region}import{existsSync as Wa}from"node:fs";import{mkdir as Om,writeFile as nd}from"node:fs/promises";function Va(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(t)=>{if(i("Initializing ts-cloud Project"),Wa("cloud.config.ts")){if(!await d("cloud.config.ts already exists. Overwrite?",!1)){e("Initialization cancelled");return}}let m=t?.name||await P("Project name","my-app"),k=t?.mode||await Ko("Select deployment mode",["serverless","server"]),I=t?.region||await Ko("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),L=new s("Creating configuration file...");L.start();let z=`import { defineConfig } from '@ts-cloud/core'
32
32
 
33
33
  export default defineConfig({
34
34
  project: {
@@ -65,7 +65,7 @@ Next steps:
65
65
  1. Edit cloud.config.ts to configure your infrastructure
66
66
  2. Run 'cloud generate' to create CloudFormation templates
67
67
  3. Run 'cloud deploy' to deploy your infrastructure`,"green")}),R.command("init:server","Initialize server-based (EC2) project").action(async()=>{i("Initializing Server-Based Project"),await R.parse(["init","--mode","server"])}),R.command("init:serverless","Initialize serverless (Fargate/Lambda) project").action(async()=>{i("Initializing Serverless Project"),await R.parse(["init","--mode","serverless"])}),R.command("init:hybrid","Initialize hybrid project").action(async()=>{i("Initializing Hybrid Project"),await R.parse(["init","--mode","hybrid"])})}import{readFile as rd,writeFile as Lm}from"node:fs/promises";import{resolve as Ms}from"node:path";async function Ne(){let R=await Zi();if(!R.project)throw Error("Missing required project configuration in cloud.config.ts");return R}function bn(R){if(R)switch(R.toLowerCase()){case"porkbun":{let k=process.env.PORKBUN_API_KEY,I=process.env.PORKBUN_SECRET_KEY;if(!k||!I)throw Error("PORKBUN_API_KEY and PORKBUN_SECRET_KEY environment variables are required for Porkbun provider");return{provider:"porkbun",apiKey:k,secretKey:I}}case"godaddy":{let k=process.env.GODADDY_API_KEY,I=process.env.GODADDY_API_SECRET;if(!k||!I)throw Error("GODADDY_API_KEY and GODADDY_API_SECRET environment variables are required for GoDaddy provider");let L=process.env.GODADDY_ENVIRONMENT||"production";return{provider:"godaddy",apiKey:k,apiSecret:I,environment:L}}case"route53":{let k=process.env.AWS_REGION||"us-east-1",I=process.env.AWS_HOSTED_ZONE_ID;return{provider:"route53",region:k,hostedZoneId:I}}case"cloudflare":{let k=process.env.CLOUDFLARE_API_TOKEN;if(!k)throw Error("CLOUDFLARE_API_TOKEN environment variable is required for Cloudflare provider");return{provider:"cloudflare",apiToken:k,zoneId:process.env.CLOUDFLARE_ZONE_ID,accountId:process.env.CLOUDFLARE_ACCOUNT_ID}}default:throw Error(`Unknown DNS provider: ${R}. Supported: porkbun, godaddy, route53, cloudflare`)}if(new Ui().loadFromEnv().getAllProviders().length===0)return null;if(process.env.PORKBUN_API_KEY&&process.env.PORKBUN_SECRET_KEY)return{provider:"porkbun",apiKey:process.env.PORKBUN_API_KEY,secretKey:process.env.PORKBUN_SECRET_KEY};if(process.env.GODADDY_API_KEY&&process.env.GODADDY_API_SECRET)return{provider:"godaddy",apiKey:process.env.GODADDY_API_KEY,apiSecret:process.env.GODADDY_API_SECRET,environment:process.env.GODADDY_ENVIRONMENT||"production"};if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE||process.env.AWS_REGION)return{provider:"route53",region:process.env.AWS_REGION||"us-east-1",hostedZoneId:process.env.AWS_HOSTED_ZONE_ID};if(process.env.CLOUDFLARE_API_TOKEN)return{provider:"cloudflare",apiToken:process.env.CLOUDFLARE_API_TOKEN,zoneId:process.env.CLOUDFLARE_ZONE_ID,accountId:process.env.CLOUDFLARE_ACCOUNT_ID};return null}function Vr(R){let t=bn(R);if(!t)throw Error("No DNS provider configured. Set environment variables for Porkbun (PORKBUN_API_KEY, PORKBUN_SECRET_KEY), GoDaddy (GODADDY_API_KEY, GODADDY_API_SECRET), Cloudflare (CLOUDFLARE_API_TOKEN), or Route53 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)");return B(t)}async function Fm(R){let t=await Ne(),m=y(process.cwd(),t),k=R??Object.keys(t.environments??{})[0]??"production",I=m.environments.get(k);if(!I)throw m.store.close(),Error(`Environment ${k} was not found.`);let L=t.project?.region??"us-east-1",z=_(process.cwd()),Y=new Or(m.store),Z=new Ur(Y,{encryptionKey:z,backends:[new Pt(m.store,z),new $r(new J(L),L),new Lr(new Ze(L),L),new Mr]}),X=m.store.getActorByExternalId("system","cli")??m.store.createActor({kind:"system",externalId:"cli",displayName:"ts-cloud CLI"});return await Cn(Z,m,t,X.id),{config:t,controlPlane:m,env:k,environmentRecord:I,store:Y,service:Z,actor:X}}async function Hr(R,t){let m=await Fm(R);try{return await t(m)}finally{m.controlPlane.store.close()}}async function Dn(R){try{await R()}catch(t){r(t instanceof Error?t.message:String(t))}}function jm(R){return R.map((t)=>[t.key,t.kind,t.scope.type,t.inherited?"inherited":t.overridden?"override":"direct",t.kind==="secret"?t.backend??"restricted":t.value??"",t.backendVersion??"—",t.required?"required":"optional",t.updatedAt])}function id(R,t=process.env){if(R.value!=null)throw Error("Secret values are not accepted in command arguments; use --from-env or the interactive prompt.");if(!R.fromEnv)return;let m=t[R.fromEnv];if(!m)throw Error(`${R.fromEnv} is empty or unavailable.`);return m}function nr(R,t){let m=t.scope??"environment";if(m==="project")return{type:m,id:R.controlPlane.project.id};if(m==="environment"){let k=t.target?R.controlPlane.store.listEnvironments(R.controlPlane.project.id).find((I)=>I.id===t.target||I.slug===t.target):R.environmentRecord;if(!k)throw Error(`Environment ${t.target} was not found.`);return{type:m,id:k.id,environmentId:k.id}}if(m==="service"){let k=R.controlPlane.store.listResources(R.controlPlane.project.id),I=k.find((L)=>L.id===t.target||L.slug===t.target);if(!I)throw Error("Service scope requires --target with a resource ID or slug.");return{type:m,id:I.id,environmentId:I.environmentId,resourceId:I.id}}if(m==="function"){let k=R.controlPlane.store.listResources(R.controlPlane.project.id),I=k.find((L)=>L.kind==="function"&&(L.id===t.target||L.slug===t.target));if(!I)throw Error("Function scope requires --target with a function resource ID or slug.");return{type:m,id:I.id,environmentId:I.environmentId,resourceId:I.id}}if(m==="preview"){let k=new Fe(R.controlPlane.store).listInstances({projectId:R.controlPlane.project.id}).find((I)=>I.id===t.target||I.name===t.target);if(!k)throw Error("Preview scope requires --target with a preview ID or name.");return{type:m,id:k.id,environmentId:k.baseEnvironmentId,resourceId:k.resourceId,previewId:k.id}}throw Error("--scope must be project, environment, service, function, or preview.")}function qa(R){let t=R??"local_encrypted";if(!["local_encrypted","aws_secrets_manager","aws_ssm","external"].includes(t))throw Error("--backend must be local_encrypted, aws_secrets_manager, aws_ssm, or external.");return t}function $o(R,t,m){let k=R.store.find(R.controlPlane.project.id,m,t);if(!k)throw Error(`${t} was not found in the selected scope.`);return k}async function Bm(R,t){if(R==="secret")return id(t)??await P("Enter secret value (input is write-only)","");if(t.fromEnv){let m=process.env[t.fromEnv];if(m==null)throw Error(`${t.fromEnv} is unavailable.`);return m}if(t.value!=null)return t.value;return await P("Enter variable value","")}function Gr(R){return R.option("--env <environment>","Dashboard environment").option("--scope <scope>","project, environment, service, function, or preview",{default:"environment"}).option("--target <id>","Environment, resource, function, or preview ID/name")}function Ha(R){R.command("config","Show validated file configuration").action(async()=>Dn(async()=>{let t=await Ne();console.log(JSON.stringify(t,null,2))})),R.command("config:validate","Validate configuration file").action(async()=>Dn(async()=>{let t=await Ne();if(!t.project?.name||!t.project?.slug||!t.mode)throw Error("project.name, project.slug, and mode are required.");n(`Configuration is valid: ${t.project.name} · ${t.mode} · ${t.project.region||"us-east-1"}`)})),Gr(R.command("config:list","List scoped variables and write-only secret metadata")).option("--kind <kind>","variable or secret").option("--search <text>","Filter key names").option("--json","Print structured JSON").action(async(t)=>Dn(async()=>Hr(t.env,async(m)=>{let k=nr(m,t),I=["variable","secret"].includes(t.kind??"")?t.kind:void 0,L=m.service.list({projectId:m.controlPlane.project.id,scope:k,kind:I,search:t.search,canReadSecretMetadata:!0});if(t.json)console.log(JSON.stringify(L,null,2));else c(["Key","Kind","Scope","Precedence","Value/backend","Backend version","Requirement","Updated"],jm(L))}))),Gr(R.command("config:set <key>","Create or replace a scoped variable or secret")).option("--value <value>","Plaintext variable value only").option("--from-env <name>","Read the value from an environment variable").option("--secret","Store a write-only secret").option("--backend <backend>","local_encrypted, aws_secrets_manager, aws_ssm, or external").option("--reference <uri>","External provider reference").option("--required","Fail deployments when unavailable").option("--confirm <key>","Exact key confirmation for production replacements").option("--json","Print structured JSON").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let I=nr(k,m),L=m.secret?"secret":"variable",z=L==="secret"?qa(m.backend):void 0,Y=z==="external"?void 0:await Bm(L,m),Z=await k.service.set({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,scope:I,key:t,kind:L,value:Y,reference:m.reference,backend:z,required:!!m.required,confirmed:m.confirm===t,actorId:k.actor.id,idempotencyKey:`cli:${crypto.randomUUID()}`});if(m.json)console.log(JSON.stringify({entry:k.service.list({projectId:k.controlPlane.project.id,scope:I,canReadSecretMetadata:!0}).find((X)=>X.id===Z.entry.id),mutation:Z.mutation,warnings:Z.warnings},null,2));else n(`${t}: ${Z.mutation.added.length?"created":Z.mutation.changed.length?"updated":"unchanged"}; ${Z.mutation.affectedResourceIds.length} affected service(s).`)}))),Gr(R.command("config:delete <key>","Delete a scoped variable or secret")).option("--confirm <key>","Exact key confirmation").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let I=$o(k,t,nr(k,m));await k.service.remove({entryId:I.id,expectedVersion:I.version,confirmed:m.confirm===t,actorId:k.actor.id}),n(`Deleted ${t}.`)}))),Gr(R.command("config:import <file>","Validate and import a dotenv file")).option("--secret-keys <keys>","Comma-separated secret keys").option("--backend <backend>","Secret backend").option("--confirm <word>","Use import for production replacement confirmation").option("--json","Print structured JSON").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let I=await k.service.importDotenv({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,scope:nr(k,m),source:await rd(Ms(t),"utf8"),secretKeys:m.secretKeys?.split(",").map((L)=>L.trim()).filter(Boolean),backend:qa(m.backend),confirmed:m.confirm==="import",actorId:k.actor.id,idempotencyKey:`cli-import:${crypto.randomUUID()}`});if(!I.document.valid)throw Error(I.document.diagnostics.map((L)=>`line ${L.line}: ${L.message}`).join(`
68
- `));if(m.json)console.log(JSON.stringify({mutation:I.mutation,diagnostics:I.document.diagnostics,warnings:I.warnings},null,2));else n(`Imported ${I.mutation?.added.length??0} new, ${I.mutation?.changed.length??0} changed, and ${I.mutation?.unchanged.length??0} unchanged entries.`)}))),Gr(R.command("config:plan <file>","Preview dotenv drift using key names only")).option("--remove-missing","Include managed keys absent from the file").option("--json","Print structured JSON").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let{parseDotenv:I}=await import("./chunk-5hmrqjmq.js"),L=I(await rd(Ms(t),"utf8"));if(!L.valid)throw Error(L.diagnostics.map((Y)=>`line ${Y.line}: ${Y.message}`).join(`
68
+ `));if(m.json)console.log(JSON.stringify({mutation:I.mutation,diagnostics:I.document.diagnostics,warnings:I.warnings},null,2));else n(`Imported ${I.mutation?.added.length??0} new, ${I.mutation?.changed.length??0} changed, and ${I.mutation?.unchanged.length??0} unchanged entries.`)}))),Gr(R.command("config:plan <file>","Preview dotenv drift using key names only")).option("--remove-missing","Include managed keys absent from the file").option("--json","Print structured JSON").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let{parseDotenv:I}=await import("./chunk-b61yq5rn.js"),L=I(await rd(Ms(t),"utf8"));if(!L.valid)throw Error(L.diagnostics.map((Y)=>`line ${Y.line}: ${Y.message}`).join(`
69
69
  `));let z=k.service.plan({projectId:k.controlPlane.project.id,scope:nr(k,m),values:L.values,removeMissing:!!m.removeMissing});if(m.json)console.log(JSON.stringify(z,null,2));else c(["Action","Keys"],[["Add",z.added.join(", ")||"—"],["Change",z.changed.join(", ")||"—"],["Remove",z.removed.join(", ")||"—"],["Unchanged",z.unchanged.join(", ")||"—"]]),e(`${z.affectedResourceIds.length} affected service(s); no secret values were printed.`)}))),Gr(R.command("config:export [file]","Export plaintext variables only as dotenv")).action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let I=k.service.exportVariables({projectId:k.controlPlane.project.id,scope:nr(k,m)});if(t)await Lm(Ms(t),I,{mode:384}),n(`Exported variables to ${Ms(t)}; secrets were excluded.`);else process.stdout.write(I)}))),Gr(R.command("config:transfer <key>","Copy or move an entry between scopes")).option("--to-scope <scope>","Destination scope").option("--to-target <id>","Destination ID or slug").option("--move","Remove the source after copying").option("--confirm <key>","Exact key confirmation").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{let I=nr(k,m),L=$o(k,t,I),z=nr(k,{env:m.env,scope:m.toScope,target:m.toTarget}),Y=await k.service.transfer({entryId:L.id,targetScope:z,mode:m.move?"move":"copy",confirmed:m.confirm===t,actorId:k.actor.id,idempotencyKey:`cli-transfer:${crypto.randomUUID()}`});n(`${t} ${m.move?"moved":"copied"}; ${Y.mutation.affectedResourceIds.length} affected service(s).`)}))),Gr(R.command("config:reveal <key>","Reveal a secret after exact confirmation")).option("--confirm <key>","Exact key confirmation").action(async(t,m)=>Dn(async()=>Hr(m.env,async(k)=>{if(m.confirm!==t)throw Error(`Use --confirm ${t} to reveal this secret.`);let I=$o(k,t,nr(k,m));console.log(await k.service.reveal({entryId:I.id,canRevealSecrets:!0,recentlyAuthenticated:!0,actorId:k.actor.id}))}))),Gr(R.command("config:env","Backward-compatible variable management")).option("--list","List variables").option("--set <key=value>","Set a variable").option("--unset <key>","Delete a variable").option("--environment <environment>","Target environment").action(async(t)=>Dn(async()=>Hr(t.environment??t.env,async(m)=>{let k=nr(m,{env:t.environment,scope:"environment",target:t.environment});if(t.list)c(["Key","Value","Updated"],m.service.list({projectId:m.controlPlane.project.id,scope:k,kind:"variable"}).map((I)=>[I.key,I.value??"",I.updatedAt]));else if(t.set){let I=t.set.indexOf("=");if(I<1)throw Error("Use --set KEY=VALUE.");let L=t.set.slice(0,I),z=t.set.slice(I+1);await m.service.set({organizationId:m.controlPlane.organization.id,projectId:m.controlPlane.project.id,scope:k,key:L,kind:"variable",value:z,confirmed:!1,actorId:m.actor.id}),n(`Set ${L}.`)}else if(t.unset){let I=$o(m,t.unset,k);await m.service.remove({entryId:I.id,expectedVersion:I.version,confirmed:await d(`Delete ${I.key}?`,!1),actorId:m.actor.id}),n(`Deleted ${I.key}.`)}else e("Use --list, --set KEY=VALUE, or --unset KEY.")}))),Gr(R.command("config:secrets","Backward-compatible write-only secret management")).option("--list","List secret metadata").option("--create <key>","Create a secret").option("--update <key>","Rotate a secret").option("--get <key>","Reveal a secret").option("--delete <key>","Delete a secret").option("--from-env <name>","Read new value from an environment variable").option("--backend <backend>","Secret backend").option("--confirm <key>","Exact key confirmation").action(async(t)=>Dn(async()=>Hr(t.env,async(m)=>{let k=nr(m,t);if(t.list)c(["Key","Backend","Version","Rotated"],m.service.list({projectId:m.controlPlane.project.id,scope:k,kind:"secret",canReadSecretMetadata:!0}).map((I)=>[I.key,I.backend??"restricted",I.backendVersion??"—",I.rotatedAt??"never"]));else if(t.create||t.update){let I=t.create??t.update,L=id(t)??await P("Enter secret value (write-only)","");await m.service.set({organizationId:m.controlPlane.organization.id,projectId:m.controlPlane.project.id,scope:k,key:I,kind:"secret",value:L,backend:qa(t.backend),confirmed:t.confirm===I,actorId:m.actor.id}),n(`${I} ${t.update?"rotated":"created"}.`)}else if(t.get){if(t.confirm!==t.get)throw Error(`Use --confirm ${t.get} to reveal.`);let I=$o(m,t.get,k);console.log(await m.service.reveal({entryId:I.id,canRevealSecrets:!0,recentlyAuthenticated:!0,actorId:m.actor.id}))}else if(t.delete){let I=$o(m,t.delete,k);await m.service.remove({entryId:I.id,expectedVersion:I.version,confirmed:t.confirm===I.key,actorId:m.actor.id}),n(`Deleted ${I.key}.`)}else e("Use --list, --create, --update, --get, or --delete.")})))}import{existsSync as Zm}from"node:fs";import{readFile as Qm,writeFile as Xm}from"node:fs/promises";async function zs(R){let t=[];for(let m of R.steps)try{t.push({step:m,state:await m.satisfied()?"satisfied":"pending"})}catch(k){t.push({step:m,state:"unknown",reason:k instanceof Error?k.message:String(k)})}return t}function od(R){return R.filter((t)=>t.state!=="satisfied")}function _m(R){return od(R).some((t)=>t.step.destructive===!0)}function Us(R,t){let m=od(t),k=[`${R.operation} ${R.target}`];if(m.length===0)return k.push(" Nothing to do — every step is already satisfied."),k;for(let{step:L,state:z,reason:Y}of t){let Z=z==="satisfied"?"ok ":z==="unknown"?"? ":"→ ",X=[L.destructive?"DESTRUCTIVE":"",z==="satisfied"?"already done":""].filter(Boolean);if(k.push(` ${Z}${L.title}${X.length>0?` [${X.join(", ")}]`:""}`),L.change)k.push(` ${L.change.from} → ${L.change.to}`);if(Y)k.push(` could not check: ${Y}`)}let I=m.filter((L)=>L.step.destructive).length;return k.push(` ${m.length} step(s) would run`+(I>0?`, ${I} irreversible — re-run with --confirm ${R.target}`:"")),k}async function Ws(R,t,m={}){let k={operation:R.operation,target:R.target,steps:[],success:!0};if(_m(t)&&m.confirm!==R.target)throw Error(`${R.operation} includes an irreversible step. Re-run with --confirm ${R.target} to authorize it.`);for(let{step:I,state:L}of t){if(L==="satisfied"){k.steps.push({id:I.id,title:I.title,state:"skipped"}),m.log?.(`skip ${I.title} (already done)`);continue}m.audit?.({operation:R.operation,target:R.target,step:I.id,state:"started"});try{await I.apply(),k.steps.push({id:I.id,title:I.title,state:"applied"}),m.log?.(`done ${I.title}`),m.audit?.({operation:R.operation,target:R.target,step:I.id,state:"applied"})}catch(z){let Y=z instanceof Error?z.message:String(z);return k.steps.push({id:I.id,title:I.title,state:"failed",error:Y}),k.success=!1,m.log?.(`FAIL ${I.title}: ${Y}`),m.audit?.({operation:R.operation,target:R.target,step:I.id,state:"failed",error:Y}),k}}return k}function ko(R,t){return`/tmp/ts-cloud-move-${R}-${t}.tar.gz`}function sd(R,t){return`${R}-${t}*.service`}function _t(R){return`'${R.split("'").join("'\\''")}'`}function Mm(R,t){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${_t(ad(R,t))} || true); do`,' systemctl stop "$unit" 2>/dev/null || true',"done"].join(`
70
70
  `)}function ad(R,t){return`^${R}-${t}-((queue|daemon)-.*|scheduler)\\.service$`}function zm(R,t){return cd(ad(R,t))}function cd(R){return[`ls /etc/systemd/system/ 2>/dev/null | grep -E ${_t(R)} | while read -r unit; do`,' systemctl is-active "$unit" >/dev/null 2>&1 && echo "active:$unit" || true',"done"].join(`
71
71
  `)}function Um(R){return!R.split(`
@@ -309,13 +309,13 @@ ${t.loadManagement?.enabled?`
309
309
  Generated ${Se} resources:`);let Re=De.getResources(),Pe={};for(let Le of Object.values(Re)){let Be=Le.Type;Pe[Be]=(Pe[Be]||0)+1}let ze=Object.entries(Pe).sort((Le,Be)=>Be[1]-Le[1]);for(let[Le,Be]of ze)e(` - ${Le}: ${Be}`);e(`
310
310
  Next steps:
311
311
  1. Review the generated templates in ${I}/
312
- 2. Run 'cloud deploy' to deploy your infrastructure`)}catch(k){m.fail("Failed to generate templates"),r(k instanceof Error?k.message:"Unknown error")}}),R.command("generate:preview","Preview what will be generated").action(async()=>{En("generate:preview",{message:"The legacy preview renderer has no stable output contract.",nextAction:"Run `cloud generate` into a temporary output directory and inspect the generated templates."})}),R.command("diff","Show diff between local config and deployed stack").alias("generate:diff").option("--stack <name>","Stack name to compare against").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{i("Infrastructure Diff");try{let m=await Ne(),k=t?.env||"production",{resolveProjectStackName:I}=await import("./chunk-7848wre2.js"),L=t?.stack||I(m,k),z=m.project.region||"us-east-1";e(`Stack: ${L}`),e(`Region: ${z}`),e(`Environment: ${k}`),u("Generating template from configuration...");let Y=new Ro({config:m,environment:k});Y.generate();let Z=Y.toJSON(),X=JSON.parse(Z);u("Fetching deployed template...");let ne=new v(z),ie=null;try{let Re=await ne.getTemplate(L);if(Re.TemplateBody)ie=JSON.parse(Re.TemplateBody)}catch(Re){if(Re.message?.includes("does not exist")){a(`Stack "${L}" does not exist yet`),e(`
312
+ 2. Run 'cloud deploy' to deploy your infrastructure`)}catch(k){m.fail("Failed to generate templates"),r(k instanceof Error?k.message:"Unknown error")}}),R.command("generate:preview","Preview what will be generated").action(async()=>{En("generate:preview",{message:"The legacy preview renderer has no stable output contract.",nextAction:"Run `cloud generate` into a temporary output directory and inspect the generated templates."})}),R.command("diff","Show diff between local config and deployed stack").alias("generate:diff").option("--stack <name>","Stack name to compare against").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{i("Infrastructure Diff");try{let m=await Ne(),k=t?.env||"production",{resolveProjectStackName:I}=await import("./chunk-vr9jcw65.js"),L=t?.stack||I(m,k),z=m.project.region||"us-east-1";e(`Stack: ${L}`),e(`Region: ${z}`),e(`Environment: ${k}`),u("Generating template from configuration...");let Y=new Ro({config:m,environment:k});Y.generate();let Z=Y.toJSON(),X=JSON.parse(Z);u("Fetching deployed template...");let ne=new v(z),ie=null;try{let Re=await ne.getTemplate(L);if(Re.TemplateBody)ie=JSON.parse(Re.TemplateBody)}catch(Re){if(Re.message?.includes("does not exist")){a(`Stack "${L}" does not exist yet`),e(`
313
313
  This will be a new deployment with the following resources:`);let Pe=Object.keys(X.Resources||{}).length;e(`
314
314
  Resources to create: ${Pe}`);let ze={};for(let Le of Object.values(X.Resources||{})){let Be=Le.Type;ze[Be]=(ze[Be]||0)+1}for(let[Le,Be]of Object.entries(ze).sort((Ve,ct)=>ct[1]-Ve[1]))e(` + ${Le}: ${Be}`);e("\nRun `cloud deploy` to create this stack");return}throw Re}u("Comparing templates...");let se=ie.Resources||{},be=X.Resources||{},Ae=new Set(Object.keys(se)),le=new Set(Object.keys(be)),ke=[];for(let Re of le)if(!Ae.has(Re))ke.push(Re);let De=[];for(let Re of Ae)if(!le.has(Re))De.push(Re);let Se=[];for(let Re of le)if(Ae.has(Re)){let Pe=JSON.stringify(se[Re]),ze=JSON.stringify(be[Re]);if(Pe!==ze)Se.push(Re)}if(ke.length===0&&De.length===0&&Se.length===0){n(`
315
315
  No changes detected - infrastructure is up to date`);return}if(e(`
316
316
  Changes detected:
317
317
  `),ke.length>0){n(`Resources to add (${ke.length}):`);for(let Re of ke){let Pe=be[Re].Type;e(` + ${Re} (${Pe})`)}console.log()}if(De.length>0){r(`Resources to remove (${De.length}):`);for(let Re of De){let Pe=se[Re].Type;e(` - ${Re} (${Pe})`)}console.log()}if(Se.length>0){a(`Resources to modify (${Se.length}):`);for(let Re of Se){let Pe=be[Re].Type;e(` ~ ${Re} (${Pe})`)}console.log()}e("Summary:"),e(` - Add: ${ke.length}`),e(` - Remove: ${De.length}`),e(` - Modify: ${Se.length}`),e("\nRun `cloud deploy` to apply these changes")}catch(m){r(`Diff failed: ${m.message}`)}})}function Bi(R,t=0){let m=Number(R);return Number.isFinite(m)?m:t}function Za(R){return Bi(R)*1024}function mp(R){let t=R?.date?.trim(),m=R?.time?.trim();if(!t||!m)return null;let k=new Date(`${t}T${m}Z`);return Number.isFinite(k.getTime())?k.toISOString():null}function pp(R,t,m){let k;try{k=JSON.parse(R)}catch{return[]}let I=(k?.sysstat?.hosts??[]).flatMap((z)=>z.statistics??[]),L=[];for(let z of I){let Y=mp(z.timestamp);if(!Y)continue;let Z=new Date(Y).getTime();if(Z<t.getTime()||Z>m.getTime())continue;let X=z["cpu-load"]?.find((ie)=>ie.cpu==="all")??z["cpu-load"]?.[0],ne=Bi(X?.idle,100);L.push({timestamp:Y,cpuUsedPercent:Math.max(0,Math.min(100,100-ne)),cpuUserPercent:Bi(X?.user),cpuSystemPercent:Bi(X?.system),cpuIowaitPercent:Bi(X?.iowait),memoryUsedPercent:Bi(z.memory?.["memused-percent"]),memoryUsedBytes:Za(z.memory?.memused),memoryAvailableBytes:Za(z.memory?.avail),swapUsedPercent:Bi(z.memory?.["swpused-percent"]),swapUsedBytes:Za(z.memory?.swpused)})}return L.sort((z,Y)=>z.timestamp.localeCompare(Y.timestamp))}function fp(R){return Object.fromEntries(Object.entries(R.time_series??{}).map(([t,m])=>[t,(m.values??[]).map(([k,I])=>({timestamp:new Date(Number(k)*1000).toISOString(),value:Bi(I,Number.NaN)})).filter((k)=>Number.isFinite(k.value))]))}function hd(R){return R.length?R.reduce((t,m)=>t+m,0)/R.length:null}function Qa(R){return R.length?Math.max(...R):null}function gp(R){return R.length?Math.min(...R):null}async function yd(R){let[t,m]=await Promise.all([R.client.getServerMetrics(R.serverId,{types:["cpu","disk","network"],start:R.from,end:R.to,step:R.step}),_e(R.remote.host,"LC_ALL=C sadf -j -- -u -r -S",R.remote).catch(()=>"")]),k=pp(m,R.from,R.to),I=fp(t),z=(I.cpu??[]).map((ie)=>Math.max(0,Math.min(100,ie.value/Math.max(1,R.cores)))),Y=k.map((ie)=>ie.cpuUsedPercent),Z=z.length?z:Y,X=k.map((ie)=>ie.memoryUsedPercent),ne=k.map((ie)=>ie.swapUsedPercent);return{from:R.from.toISOString(),to:R.to.toISOString(),cores:R.cores,host:k,provider:I,summary:{cpuAveragePercent:hd(Z),cpuPeakPercent:Qa(Z),memoryAveragePercent:hd(X),memoryPeakPercent:Qa(X),memoryMinimumAvailableBytes:gp(k.map((ie)=>ie.memoryAvailableBytes)),swapPeakPercent:Qa(ne)}}}function hp(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 t of R.split(".")){if(t.length===0)throw Error(`'${R}' has an empty label — a hostname cannot contain '..'.`);if(t.length>63)throw Error(`'${t}' is longer than the 63 characters a hostname label allows.`);if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(t))throw Error(`'${t}' is not a valid hostname label. Use letters, digits and hyphens, not starting or ending with a hyphen.`)}}async function vd(R,t,m){if(hp(t),R===t)throw Error(`'${R}' is already named that.`);if((await m.takenNames()).some((L)=>L===t&&L!==R))throw Error(`'${t}' is already taken. Server names have to be unique within a provider project.`);let I=[];if(m.providerName&&m.renameProvider){let{providerName:L,renameProvider:z}=m;I.push({id:"provider",title:"Rename the server at the provider",change:{from:R,to:t},satisfied:async()=>await L()===t,apply:()=>z(t)})}if(m.stateName&&m.writeStateName){let{stateName:L,writeStateName:z}=m;I.push({id:"state-pin",title:"Update the recorded name in the local driver state",change:{from:R,to:t},satisfied:async()=>{let Y=await L();return Y===void 0||Y===t},apply:()=>z(t)})}if(m.remoteHostname&&m.setRemoteHostname){let{remoteHostname:L,setRemoteHostname:z}=m;I.push({id:"hostname",title:"Set the hostname on the box",change:{from:R,to:t},satisfied:async()=>await L()===t,apply:()=>z(t)})}return I.push({id:"inventory",title:"Rename the fleet inventory record",change:{from:R,to:t},satisfied:async()=>m.inventoryName()===t,apply:async()=>{await m.renameInventory(t)}}),{operation:"server:rename",target:R,steps:I}}function bd(R){let t=`'${R.replace(/'/g,`'"'"'`)}'`;return["set -eu",'TS_CLOUD_OLD="$(hostname)"',`hostnamectl set-hostname ${t} 2>/dev/null || { echo ${t} > /etc/hostname && hostname ${t}; }`,'if grep -q "^127.0.1.1" /etc/hosts; then',` TS_CLOUD_HOSTS="$(sed -E "s/^127\\.0\\.1\\.1.*/127.0.1.1\\t${R}/" /etc/hosts)"`,` printf '%s\\n' "$TS_CLOUD_HOSTS" > /etc/hosts`,"else",` printf '127.0.1.1\\t%s\\n' ${t} >> /etc/hosts`,"fi",'printf "%s -> %s\\n" "$TS_CLOUD_OLD" "$(hostname)"'].join(`
318
- `)}async function yp(){let R=await Ne(),t=y(process.cwd(),R),m=new xe(t.store),k=new Un(m,[new lt("aws"),new lt("hetzner"),new lt("ssh")]);return{controlPlane:t,store:m,service:k}}async function bi(R){let t=await yp();try{return await R(t)}finally{t.controlPlane.store.close()}}var Wi=(R,t)=>{let m=R.store.list(R.controlPlane.project.id).find((k)=>k.id===t||k.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},kn=(R)=>{r(R instanceof Error?R.message:String(R)),process.exitCode=1};function Xa(R,t){let m=Number.parseInt(R??"",10);return Number.isFinite(m)&&m>=0?m:t}function vp(R="3h"){let t=R.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ss(R,t="%"){return R==null?"unavailable":`${R.toFixed(1)}${t}`}async function bp(R,t){let m=await Ne();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let k=t.env??process.env.CLOUD_ENV??"production",I=T(m,k),L=await ge(I);if(!L?.serverId)throw Error(`No pinned Hetzner server was found for ${I}.`);if(![L.serverName,String(L.serverId),L.stackName].includes(R))throw Error(`Refusing to read ${R}: project state is pinned to ${L.serverName}.`);let z=St(m),Y=new Oe({apiToken:Cr(z.apiToken,m)}),Z=await Y.getServer(L.serverId),X=L.publicIp??Z.public_net.ipv4?.ip;if(!X)throw Error(`Server ${Z.name} has no public IPv4 address.`);let ne=new Date,ie=new Date(ne.getTime()-vp(t.range)),se=Math.min(3600,Math.max(60,Xa(t.step,60))),be=await yd({client:Y,serverId:Z.id,cores:Math.max(1,Number(Z.server_type.cores)||1),from:ie,to:ne,step:se,remote:{host:X,user:L.sshUser??z.sshUser,identityFile:z.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:Z.name,result:be},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[Z.name,`${be.from} to ${be.to}`,`${ss(be.summary.cpuAveragePercent)} / ${ss(be.summary.cpuPeakPercent)}`,`${ss(be.summary.memoryAveragePercent)} / ${ss(be.summary.memoryPeakPercent)}`,be.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(be.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ss(be.summary.swapPeakPercent)]])}function wd(R){let t=R.targetType.prices?.find((m)=>m.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:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function wp(R){let t=wd(R);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function Sp(R,t,m){let k=await Ne();if(k.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let I=m.env??process.env.CLOUD_ENV??"production",L=T(k,I),z=await ge(L),Y=St(k),Z=new Oe({apiToken:Cr(Y.apiToken,k)}),ne=z&&(R===z.serverName||R===String(z.serverId)||R===z.stackName)?await Z.getServer(z.serverId):(await Z.listServers()).find((Le)=>Le.name===R||String(Le.id)===R);if(!ne)throw Error(`Hetzner server ${R} was not found.`);if(z?.serverId&&z.serverId!==ne.id)throw Error(`Refusing to resize ${R}: project state is pinned to server ${z.serverId}.`);let ie=tt(t),se=m.upgradeDisk!==!1,be=await rt(Z,ne.id,ie,se);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:wd(be)},null,2));else wp(be);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${ne.name} to execute.`);return}if(m.confirm!==ne.name)throw Error(`Resize requires --confirm ${ne.name}.`);let Ae=z?.publicIp??ne.public_net.ipv4?.ip;if(!Ae)throw Error(`Server ${ne.name} has no public IPv4 address for verification.`);let le={host:Ae,user:z?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},ke=await $s(L),De=new Date().toISOString(),Se={schemaVersion:1,operationId:ke?.targetType===ie&&ke.serverId===ne.id?ke.operationId:crypto.randomUUID(),stackName:L,serverId:ne.id,serverName:ne.name,sourceType:be.currentType.name,targetType:ie,upgradeDisk:se,phase:"planning",status:"running",attempts:ke?.targetType===ie?ke.attempts:0,startedAt:ke?.targetType===ie?ke.startedAt:De,updatedAt:De,manifest:ke?.targetType===ie?ke.manifest:void 0};await Ct(Se);let Re=Xa(m.pollSeconds,900)*1000,Pe=Xa(m.maxWaitMinutes,0)*60000,ze=Date.now();for(;;){let Le=await rt(Z,ne.id,ie,se);if(!Le.capacityAvailable&&!Le.alreadyComplete){if(Se={...Se,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await Ct(Se),!m.wait){if(!m.json)e(`${ie} has no capacity in ${Le.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Pe>0&&Date.now()-ze>=Pe)throw Error(`Timed out waiting for ${ie} capacity in ${Le.location}.`);if(!m.json)e(`Waiting ${Math.round(Re/1000)} seconds for ${ie} capacity...`);await Bun.sleep(Re);continue}let Be=await Ls(L);try{let Ve=await(async()=>{try{return Se={...Se,status:"running",attempts:Se.attempts+1,updatedAt:new Date().toISOString()},await Ct(Se),await Tr({client:Z,serverId:ne.id,targetType:ie,upgradeDisk:se,resumeFromOff:Se.phase==="shutting-down"||Se.phase==="resizing"||Se.phase==="powering-on"||Se.phase==="verifying",manifest:Se.manifest,hooks:{preflight:async()=>{let ct=await wi(le);return Se={...Se,manifest:ct,updatedAt:new Date().toISOString()},await Ct(Se),ct},afterBoot:async(ct,Dt,nt,xt)=>Ai(le,Dt,nt,xt),onPhase:async(ct,Dt)=>{if(Se={...Se,phase:ct,status:ct==="waiting-capacity"?"waiting-capacity":ct==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await Ct(Se),!m.json)e(`${ct}${Dt?` ${JSON.stringify(Dt)}`:""}`)}}})}finally{await Be()}})();if(Se={...Se,status:Ve.status==="completed"||Ve.status==="already-complete"?"completed":Ve.status==="recovered"?"recovered":"waiting-capacity",lastError:Ve.status==="recovered"?Ve.error:void 0,updatedAt:new Date().toISOString()},await Ct(Se),m.json)console.log(JSON.stringify({schemaVersion:1,result:Ve},null,2));else if(Ve.status==="completed"||Ve.status==="already-complete")n(`${ne.name} is on ${ie} and passed full post-boot verification.`);else if(Ve.status==="recovered"&&Ve.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(Re/1000)} seconds before retry.`),await Bun.sleep(Re);continue}else if(Ve.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${Ve.error}`);return}catch(Ve){throw Se={...Se,status:"failed",lastError:Ve instanceof Error?Ve.message:String(Ve),updatedAt:new Date().toISOString()},await Ct(Se),Ve}}}async function Cp(R,t){let m=await Ne();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let k=t.env??process.env.CLOUD_ENV??"production",I=T(m,k),L=await ge(I);if(!L?.serverId)throw Error(`No pinned Hetzner server was found for ${I}.`);if(![L.serverName,String(L.serverId),L.stackName].includes(R))throw Error(`Refusing to optimize ${R}: project state is pinned to ${L.serverName}.`);let z=St(m),Y=new Oe({apiToken:Cr(z.apiToken,m)}),Z=await Y.getServer(L.serverId),X=L.publicIp??Z.public_net.ipv4?.ip;if(!X)throw Error(`Server ${Z.name} has no public IPv4 address.`);let ne=Co(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:Z.name,plan:ne},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[Z.name,ne.firewallPorts.join(","),ne.monitoring?"on":"off",ne.autoUpdates?"on":"off",`${ne.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${Z.name} to execute.`);return}if(t.confirm!==Z.name)throw Error(`Optimization requires --confirm ${Z.name}.`);let ie={host:X,user:L.sshUser??z.sshUser,identityFile:z.sshPrivateKeyPath,connectTimeoutSec:15},se=await un(ie),be=se.routeProbes.filter((nt)=>!nt.ok),Ae=m.infrastructure?.compute,le=te(Ae)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,ke=se.failedUnits.filter((nt)=>!le.has(nt));if(ke.length>0)throw Error(`Preflight found failed services: ${ke.join(", ")}`);if(be.length>0)throw Error(`Preflight found unhealthy routes: ${be.map((nt)=>nt.domain).join(", ")}`);let De=te(Ae)?[]:Object.values(m.sites??{}).flatMap((nt)=>typeof nt?.port==="number"&&![80,443].includes(nt.port)?[nt.port]:[]),Se=dn({allowSsh:Ae?.allowSsh!==!1,sitePorts:De,allowedPorts:Ae?.firewall?.allowedPorts}),Re=(L.firewallId?(await Y.listFirewalls()).find((nt)=>nt.id===L.firewallId):void 0)??(await Y.listFirewalls()).find((nt)=>nt.name===`${m.project.slug}-${k}-app-fw`);if(!Re)throw Error(`Managed firewall for ${Z.name} was not found.`);let Pe=await Y.setFirewallRules(Re.id,Se);await Promise.all(Pe.map((nt)=>Y.waitForAction(nt.id))),await xs(m,ie);let[ze,Le]=await Promise.all([un(ie),_s(ie)]),Be=Os(ne,Le),Ve=zc(se,ze),ct=ze.routeProbes.filter((nt)=>!nt.ok);if(Ve.stoppedServices.length>0)Be.push(`services stopped: ${Ve.stoppedServices.join(", ")}`);if(Ve.changedRouteFragments.length>0)Be.push(`route fragments changed: ${Ve.changedRouteFragments.join(", ")}`);if(Ve.missingRouteIds.length>0)Be.push(`routes disappeared: ${Ve.missingRouteIds.join(", ")}`);if(Ve.changedReleaseLinks.length>0)Be.push(`release links changed: ${Ve.changedReleaseLinks.join(", ")}`);if(Ve.missingData.length>0)Be.push(`databases or volumes disappeared: ${Ve.missingData.join(", ")}`);if(ct.length>0)Be.push(`unhealthy routes: ${ct.map((nt)=>nt.domain).join(", ")}`);if(Be.length>0)throw Error(`Host optimization verification failed: ${Be.join("; ")}`);let Dt={serverId:Z.id,serverName:Z.name,services:ze.runningServices.length,routes:ze.routeIds.length,healthyDomains:ze.routeProbes.length,releaseLinks:ze.releaseLinks.length,databasesAndVolumes:ze.dataCatalog.length,report:Le};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:Dt},null,2));else n(`${Z.name} passed full host, rpx route, service, release, and data verification.`)}async function $p(R,t,m){let k=await Ne(),I=m.env??"production",L=T(k,I);await bi(async(z)=>{let Y=Wi(z,R),Z=z.store.list(z.controlPlane.project.id,!0),X=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let Re=St(k);return new Oe({apiToken:Cr(Re.apiToken,k)})}catch{return null}})():null,ne=Y.providerId?Number(Y.providerId):Number.NaN,ie=await ge(L),se=ie!=null&&ie.serverId===ne,be=new qr,Ae=Y.trustState==="pinned",le={takenNames:async()=>{let Re=Z.map((Pe)=>Pe.name);if(X)Re.push(...(await X.listServers()).map((Pe)=>Pe.name));return Re},inventoryName:()=>z.store.get(Y.id)?.name??Y.name,renameInventory:(Re)=>{z.store.update(Y.id,{name:Re})},...X&&Number.isFinite(ne)?{providerName:async()=>(await X.getServer(ne)).name,renameProvider:async(Re)=>{await X.renameServer(ne,Re)}}:{},...se?{stateName:async()=>(await ge(L))?.serverName,writeStateName:async(Re)=>{let Pe=await ge(L);if(Pe)await vt(L,{...Pe,serverName:Re})}}:{},...Ae?{remoteHostname:async()=>{let Re=await be.exec(Y,"hostname");return Re.code===0?Re.stdout.trim():void 0},setRemoteHostname:async(Re)=>{let Pe=await be.exec(Y,bd(Re));if(Pe.code!==0)throw Error(Pe.stderr.trim()||`hostname exited ${Pe.code}`)}}:{}},ke=await vd(Y.name,t,le),De=await zs(ke);if(!m.apply){let Re=[X?"":"provider record (no provider id or no API token)",se?"":"local state pin (none points at this server)",Ae?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:ke.operation,target:ke.target,rename:{from:Y.name,to:t},notCovered:Re,steps:De.map((Pe)=>({id:Pe.step.id,title:Pe.step.title,state:Pe.state,change:Pe.step.change,reason:Pe.reason}))},null,2));return}for(let Pe of Us(ke,De))console.log(Pe);for(let Pe of Re)console.log(` not covered: ${Pe}`);console.log(" Re-run with --apply to perform it.");return}let Se=await Ws(ke,De,{log:(Re)=>e(Re),audit:(Re)=>z.controlPlane.store.appendEvent({projectId:z.controlPlane.project.id,resourceId:Y.resourceId,type:`${Re.operation}.${Re.step}.${Re.state}`,level:Re.state==="failed"?"error":"info",payload:{target:Re.target,renameTo:t,...Re.error?{error:Re.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Se},null,2));if(!Se.success){let Re=Se.steps.find((Pe)=>Pe.state==="failed");throw Error(`${ke.operation} stopped at '${Re?.title}': ${Re?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function ec(R){R.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await bi(async(k)=>{let I=t?[Wi(k,t)]:k.store.list(k.controlPlane.project.id),L=I.flatMap((z)=>Object.entries(z.capabilities).map(([Y,Z])=>({server:z.name,provider:z.provider,action:Y,...Z})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:L},null,2));else c(["Server","Provider","Action","Support","Explanation"],L.map((z)=>[z.server,z.provider,z.action,z.supported?"supported":"unsupported",z.reason??"—"]))})}catch(k){kn(k)}}),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(t,m,k)=>{try{await Sp(t,m,k)}catch(I){kn(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(t,m)=>{try{await Cp(t,m)}catch(k){kn(k)}}),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(t,m)=>{try{await bp(t,m)}catch(k){kn(k)}}),R.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await bi(async(m)=>{let k=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],k.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(m){kn(m)}}),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(t,m)=>{try{await bi(async(k)=>{let I=m.provider;if(!["aws","hetzner","ssh"].includes(I)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let L=k.service.enroll({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,provider:I,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((z)=>z.split("=")).filter((z)=>z[0]&&z[1]))});n(`Enrolled ${L.name} as ${L.id}; no remote mutation was performed.`)})}catch(k){kn(k)}}),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(t,m)=>{try{await bi(async(k)=>{let I=Wi(k,t);if(I=await k.service.test(I.id),I.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${I.pendingHostKey}; review it first.`);I=k.service.reviewHostKey(I.id,m.acceptHostKey)}let L=await k.service.validate(I.id);if(m.json)console.log(JSON.stringify(L.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(L.validation?.findings??[]).map((z)=>[z.severity,z.code,z.message,z.remediation??"—"]));if(!L.validation?.valid)process.exitCode=1})}catch(k){kn(k)}}),R.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await bi(async(k)=>{let I=k.service.bootstrap(Wi(k,t).id,!!m.apply);if(I.preview)c(["Step"],I.steps.map((L)=>[L]));else n(`Bootstrap queued: ${I.operation?.id}`)})}catch(k){kn(k)}}),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(t,m,k)=>{try{await $p(t,m,k)}catch(I){kn(I)}}),R.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await bi(async(k)=>n(k.service.drain(Wi(k,t).id,!!m.complete).status))}catch(k){kn(k)}}),R.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await bi(async(m)=>{m.service.uncordon(Wi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){kn(m)}}),R.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await bi(async(k)=>{k.service.archive(Wi(k,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(k){kn(k)}}),R.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await bi(async(m)=>{let k=Wi(m,t);if(k.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let I=Bun.spawn(["ssh","-p",String(k.sshPort),"-o","StrictHostKeyChecking=yes",`${k.sshUser}@${k.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),L=await I.exited;if(L)process.exitCode=L})}catch(m){kn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])R.command(t,m).action(async(...k)=>En(t.split(" ")[0],{target:String(k[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as Sd,mkdirSync as kp,readFileSync as Ap,writeFileSync as Rp}from"node:fs";import{join as Cd,resolve as Ip}from"node:path";var tc=(R)=>{r(R instanceof Error?R.message:String(R)),process.exitCode=1};async function Pp(){try{return await Ne()}catch{return}}function xp(R){if(R===void 0)return;let t=Number(R);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${R}'.`);return t}function $d(R,t,m){let k=R?.ssh?.hosts?.find((I)=>I.host===t);return new Ir({hosts:t?[k??{host:t}]:R?.ssh?.hosts,user:m.user,port:xp(m.port),privateKeyPath:m.key,hostKey:R?.ssh?.hostKey,sudo:R?.ssh?.sudo,profile:m.profile??R?.ssh?.profile,publicIp:R?.ssh?.publicIp,lan:R?.ssh?.lan})}var kd=1073741824;function nc(R){R.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let k=await Pp(),I=$d(k,t,m),L=t??I.targetHost(),z=await I.ensureHostKey(L),{facts:Y,findings:Z}=await I.preflight(L);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:L,hostKeyFingerprint:z.fingerprint,facts:Y,findings:Z},null,2));else{if(i(`Preflight ${L}`),z.pinnedNow)e(`Pinned host key ${z.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/kd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/kd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(pn(Z)),Rr(Z))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(Rr(Z))process.exitCode=1}catch(k){tc(k)}}),R.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await Ne(),k=t.env??"production";if(t.dryRun){let z=Ar(m),[Y]=z.hosts;console.log(wr({config:m,environment:k,profile:z.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:z.lan}));return}let I=$d(m,void 0,{});i(`Adopt ${I.targetHost()}`);let L=await I.provisionComputeInfrastructure({config:m,environment:k});n(`${L.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${k}`)}catch(m){tc(m)}}),R.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in So))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let k=await Ne(),I=t.env??"production",L=Ar(k,{hosts:k.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),z=t.user??(k.ssh?.hosts?.[0]?.user??"pi"),Y=ln(t.key??"~/.ssh/id_ed25519.pub");if(!Sd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let Z=Ap(Y,"utf8").trim(),X;if(t.wifiSsid){let Ae=t.wifiPassphraseEnv??"WIFI_PASSWORD",le=process.env[Ae];if(!le)throw Error(`--wifi-ssid needs the passphrase in $${Ae} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");X={ssid:t.wifiSsid,passphrase:le,country:t.wifiCountry}}let ne=wr({config:k,environment:I,profile:L.profile,sudoUser:z!=="root"?z:void 0,lan:L.lan}),ie=vo({hostname:t.hostname,user:z,publicKey:Z,timezone:t.timezone,locale:t.locale,wifi:X},ne,{os:m}),se=Ip(t.out);kp(se,{recursive:!0});let be=Object.keys(ie.files).filter((Ae)=>Sd(Cd(se,Ae)));if(be.length>0&&!t.force)throw Error(`${be.join(", ")} already exist in ${se}; pass --force to overwrite.`);for(let[Ae,le]of Object.entries(ie.files))Rp(Cd(se,Ae),le,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(ie.files).join(", ")} to ${se}`),console.log(ie.instructions)}catch(m){tc(m)}})}async function Dp(){let R=await Ne(),t=y(process.cwd(),R),m=new Bn(t.store),k=new jn(m,new xe(t.store));return{controlPlane:t,store:m,service:k}}async function as(R){let t=await Dp();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Vs=(R)=>Object.fromEntries(String(R??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Ad=(R)=>Object.fromEntries(Object.entries(Vs(R)).map(([t,m])=>[t,Number(m)]));function rc(R){R.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>as((m)=>{let k=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],k.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(t,m)=>as((k)=>{let{purpose:I,backend:L}=m;if(!["application","build","worker","monitoring","backup"].includes(I)||!["server","ecs","asg"].includes(L))throw Error("Unsupported pool purpose or backend.");let z=k.store.createPool({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,purpose:I,backend:L,region:m.region,architecture:m.arch,labels:Vs(m.labels),requiredServerLabels:Vs(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Ad(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${z.name} (${z.id}).`)})),R.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>as((k)=>{let I=k.store.listPools(k.controlPlane.project.id).find((z)=>z.id===t||z.name===t),L=new xe(k.controlPlane.store).list(k.controlPlane.project.id).find((z)=>z.id===m||z.name===m);if(!I||!L)throw Error("Pool or server was not found.");k.store.addMember(I.id,L.id),n(`Attached ${L.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(t)=>as((m)=>{let k=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Ad(t.resources),region:t.region,architecture:t.arch,labels:Vs(t.labels)});if(t.json)console.log(JSON.stringify(k,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],k.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(t)=>as((m)=>{let k=m.store.listPools(m.controlPlane.project.id).find((L)=>L.id===t||L.name===t);if(!k)throw Error("Pool was not found.");let I=m.service.drainPool(k.id);n(`Draining ${k.name}: moved ${I.moved.length}, blocked ${I.blocked.length} stateful placement(s).`)}))}async function Ep(){let R=await Ne(),t=y(process.cwd(),R),m=new Vn(t.store),k=new zn(m);return{controlPlane:t,store:m,service:k}}async function ro(R){let t=await Ep();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var cs=(R,t)=>{let m=R.store.list(R.controlPlane.project.id).find((k)=>k.id===t||k.name===t);if(!m)throw Error("Regional topology was not found.");return m},Tp=(R)=>R.split(",").map((t,m)=>{let[k,I="aws"]=t.split(":");return{region:String(k),provider:I,role:m===0?"primary":"secondary"}}),Np=(R)=>{let t=new Set(["s3","dynamodb","secrets"]),m=R.split(",").map((I)=>I.trim()),k=m.find((I)=>!t.has(I));if(k)throw Error(`Unsupported replication kind: ${k}`);return m};function ic(R){R.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>ro((m)=>{let k=m.store.list(m.controlPlane.project.id).map((I)=>({topology:I,targets:m.store.targets(I.id),channels:m.store.channels(I.id),route:m.store.route(I.id),executions:m.store.executions(I.id)}));if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],k.map((I)=>[I.topology.name,I.topology.hostname,I.topology.activeRegion,I.topology.status,I.topology.revision??"—",`${I.channels.filter((L)=>L.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(t,m)=>ro((k)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let I=k.service.create({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,hostname:m.hostname,regions:Tp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Np(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`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(t,m,k)=>ro((I)=>c(["Step"],I.service.plan(cs(I,t).id,m,k.target).map((L)=>[L])))),R.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,k)=>ro(async(I)=>{let L=k.manifest?await Bun.file(k.manifest).json():{},z=I.service.enqueue({topologyId:cs(I,t).id,kind:"rollout",revision:m,manifest:L});n(`Regional rollout queued: ${z.operation.id}`)})),R.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${I.operation.id}`)})),R.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"failback",targetRegion:m});n(`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(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${I.operation.id}; replicated data remains retained.`)}))}var ls="0.16.82";async function Lp(){let R=await Ne(),t=y(process.cwd(),R),m=new Hn(t.store),k=new Gn(m),I=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((L)=>new qn(L,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:k,cleanup:I}}async function Ii(R){let t=await Lp();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function oc(R){R.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>Ii((m)=>{let k={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},I=[...k.manifests.map((L)=>["update",L.version,L.compatibility.compatible?"compatible":"blocked",L.compatibility.reasons.join("; ")||L.channel]),...k.campaigns.map((L)=>["upgrade",L.id,L.status,L.currentStage??L.fromVersion]),...k.cleanups.map((L)=>["cleanup",L.kind,L.status,`${L.candidates.length} items / ${L.estimatedBytes} bytes`]),...k.drills.map((L)=>["DR drill",L.scenario,L.status,L.isolatedTarget])];if(t.json)console.log(JSON.stringify(k,null,2));else c(["Area","Name / version","Status","Detail"],I)})),R.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>Ii(async(k)=>{let I=k.store.addTrustedKey({organizationId:k.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${I.name}: ${I.fingerprint}`)})),R.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,k)=>Ii(async(I)=>{let L=await Bun.file(t).json(),z=(await Bun.file(m).text()).trim(),Y=I.store.importManifest({organizationId:I.controlPlane.organization.id,keyId:k,document:L,signature:z,current:{schemaVersion:I.controlPlane.store.health().schemaVersion,currentVersion:ls,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.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(t,m,k)=>Ii((I)=>{let L=I.store.createWindow({projectId:I.controlPlane.project.id,name:t,schedule:m,timezone:k.timezone,durationMinutes:Number(k.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${L.name} (${L.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(t,m,k)=>Ii((I)=>{let L=new xe(I.controlPlane.store).list(I.controlPlane.project.id).filter((Z)=>Z.status==="ready").map((Z)=>({serverId:Z.id,target:Z.name,previousVersion:Z.bootstrapVersion??ls}));if(!L.length)L.push({target:"control-plane",previousVersion:ls});let z=I.store.createCampaign({projectId:I.controlPlane.project.id,manifestId:t,fromVersion:ls,strategy:k.strategy==="rolling"?"rolling":"canary",batchSize:Number(k.batch),healthGate:{kind:"platform"},backupId:m,targets:L}),Y=I.service.enqueueCampaign(z.id);n(`Staged upgrade queued: ${Y.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(t,m)=>Ii(async(k)=>{let I=await k.service.previewCleanup({projectId:k.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},k.cleanup);c(["ID","Candidate","Bytes"],I.candidates.map((L)=>[L.id,L.label,String(L.bytes)])),e(`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(t,m)=>Ii((k)=>{let I=k.service.enqueueCleanup(t,String(m.confirm??""));n(`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(t,m,k)=>Ii((I)=>{let L=I.store.createDrill({projectId:I.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(k.rpo),expectedRtoMinutes:Number(k.rto),recoveryPointId:k.recoveryPoint,topologyId:k.topology});n(`Planned isolated drill ${L.id}.`)})),R.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>Ii((m)=>{let k=m.service.enqueueDrill(t);n(`DR drill queued: ${k.operation.id}`)}))}async function sc(){try{return(await Ne()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function ac(R){R.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await sc(),k=new D(m);try{let{Functions:I=[]}=await k.listFunctions({MaxItems:50});if(!I.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],I.map((L)=>[L.FunctionName??"-",L.Runtime??"-",L.MemorySize?`${L.MemorySize} MB`:"-",L.Timeout?`${L.Timeout}s`:"-",L.LastModified??"-"]))}catch(I){r(`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(t,m)=>{i(`Invoking ${t}`);let k=m?.region||await sc(),I=new D(k),L=new s("Invoking function...");L.start();try{let z=await I.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(z.FunctionError){if(L.fail(`Function returned an error (${z.FunctionError})`),z.Payload)e(z.Payload);process.exitCode=1;return}if(L.succeed(`Invoked (status ${z.StatusCode})`),z.Payload)e(`
318
+ `)}async function yp(){let R=await Ne(),t=y(process.cwd(),R),m=new xe(t.store),k=new Un(m,[new lt("aws"),new lt("hetzner"),new lt("ssh")]);return{controlPlane:t,store:m,service:k}}async function bi(R){let t=await yp();try{return await R(t)}finally{t.controlPlane.store.close()}}var Wi=(R,t)=>{let m=R.store.list(R.controlPlane.project.id).find((k)=>k.id===t||k.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},kn=(R)=>{r(R instanceof Error?R.message:String(R)),process.exitCode=1};function Xa(R,t){let m=Number.parseInt(R??"",10);return Number.isFinite(m)&&m>=0?m:t}function vp(R="3h"){let t=R.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ss(R,t="%"){return R==null?"unavailable":`${R.toFixed(1)}${t}`}async function bp(R,t){let m=await Ne();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let k=t.env??process.env.CLOUD_ENV??"production",I=T(m,k),L=await ge(I);if(!L?.serverId)throw Error(`No pinned Hetzner server was found for ${I}.`);if(![L.serverName,String(L.serverId),L.stackName].includes(R))throw Error(`Refusing to read ${R}: project state is pinned to ${L.serverName}.`);let z=St(m),Y=new Oe({apiToken:Cr(z.apiToken,m)}),Z=await Y.getServer(L.serverId),X=L.publicIp??Z.public_net.ipv4?.ip;if(!X)throw Error(`Server ${Z.name} has no public IPv4 address.`);let ne=new Date,ie=new Date(ne.getTime()-vp(t.range)),se=Math.min(3600,Math.max(60,Xa(t.step,60))),be=await yd({client:Y,serverId:Z.id,cores:Math.max(1,Number(Z.server_type.cores)||1),from:ie,to:ne,step:se,remote:{host:X,user:L.sshUser??z.sshUser,identityFile:z.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:Z.name,result:be},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[Z.name,`${be.from} to ${be.to}`,`${ss(be.summary.cpuAveragePercent)} / ${ss(be.summary.cpuPeakPercent)}`,`${ss(be.summary.memoryAveragePercent)} / ${ss(be.summary.memoryPeakPercent)}`,be.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(be.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ss(be.summary.swapPeakPercent)]])}function wd(R){let t=R.targetType.prices?.find((m)=>m.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:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function wp(R){let t=wd(R);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function Sp(R,t,m){let k=await Ne();if(k.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let I=m.env??process.env.CLOUD_ENV??"production",L=T(k,I),z=await ge(L),Y=St(k),Z=new Oe({apiToken:Cr(Y.apiToken,k)}),ne=z&&(R===z.serverName||R===String(z.serverId)||R===z.stackName)?await Z.getServer(z.serverId):(await Z.listServers()).find((Le)=>Le.name===R||String(Le.id)===R);if(!ne)throw Error(`Hetzner server ${R} was not found.`);if(z?.serverId&&z.serverId!==ne.id)throw Error(`Refusing to resize ${R}: project state is pinned to server ${z.serverId}.`);let ie=tt(t),se=m.upgradeDisk!==!1,be=await rt(Z,ne.id,ie,se);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:wd(be)},null,2));else wp(be);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${ne.name} to execute.`);return}if(m.confirm!==ne.name)throw Error(`Resize requires --confirm ${ne.name}.`);let Ae=z?.publicIp??ne.public_net.ipv4?.ip;if(!Ae)throw Error(`Server ${ne.name} has no public IPv4 address for verification.`);let le={host:Ae,user:z?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},ke=await $s(L),De=new Date().toISOString(),Se={schemaVersion:1,operationId:ke?.targetType===ie&&ke.serverId===ne.id?ke.operationId:crypto.randomUUID(),stackName:L,serverId:ne.id,serverName:ne.name,sourceType:be.currentType.name,targetType:ie,upgradeDisk:se,phase:"planning",status:"running",attempts:ke?.targetType===ie?ke.attempts:0,startedAt:ke?.targetType===ie?ke.startedAt:De,updatedAt:De,manifest:ke?.targetType===ie?ke.manifest:void 0};await Ct(Se);let Re=Xa(m.pollSeconds,900)*1000,Pe=Xa(m.maxWaitMinutes,0)*60000,ze=Date.now();for(;;){let Le=await rt(Z,ne.id,ie,se);if(!Le.capacityAvailable&&!Le.alreadyComplete){if(Se={...Se,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await Ct(Se),!m.wait){if(!m.json)e(`${ie} has no capacity in ${Le.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Pe>0&&Date.now()-ze>=Pe)throw Error(`Timed out waiting for ${ie} capacity in ${Le.location}.`);if(!m.json)e(`Waiting ${Math.round(Re/1000)} seconds for ${ie} capacity...`);await Bun.sleep(Re);continue}let Be=await Ls(L);try{let Ve=await(async()=>{try{return Se={...Se,status:"running",attempts:Se.attempts+1,updatedAt:new Date().toISOString()},await Ct(Se),await Tr({client:Z,serverId:ne.id,targetType:ie,upgradeDisk:se,resumeFromOff:Se.phase==="shutting-down"||Se.phase==="resizing"||Se.phase==="powering-on"||Se.phase==="verifying",manifest:Se.manifest,hooks:{preflight:async()=>{let ct=await wi(le);return Se={...Se,manifest:ct,updatedAt:new Date().toISOString()},await Ct(Se),ct},afterBoot:async(ct,Dt,nt,xt)=>Ai(le,Dt,nt,xt),onPhase:async(ct,Dt)=>{if(Se={...Se,phase:ct,status:ct==="waiting-capacity"?"waiting-capacity":ct==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await Ct(Se),!m.json)e(`${ct}${Dt?` ${JSON.stringify(Dt)}`:""}`)}}})}finally{await Be()}})();if(Se={...Se,status:Ve.status==="completed"||Ve.status==="already-complete"?"completed":Ve.status==="recovered"?"recovered":"waiting-capacity",lastError:Ve.status==="recovered"?Ve.error:void 0,updatedAt:new Date().toISOString()},await Ct(Se),m.json)console.log(JSON.stringify({schemaVersion:1,result:Ve},null,2));else if(Ve.status==="completed"||Ve.status==="already-complete")n(`${ne.name} is on ${ie} and passed full post-boot verification.`);else if(Ve.status==="recovered"&&Ve.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(Re/1000)} seconds before retry.`),await Bun.sleep(Re);continue}else if(Ve.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${Ve.error}`);return}catch(Ve){throw Se={...Se,status:"failed",lastError:Ve instanceof Error?Ve.message:String(Ve),updatedAt:new Date().toISOString()},await Ct(Se),Ve}}}async function Cp(R,t){let m=await Ne();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let k=t.env??process.env.CLOUD_ENV??"production",I=T(m,k),L=await ge(I);if(!L?.serverId)throw Error(`No pinned Hetzner server was found for ${I}.`);if(![L.serverName,String(L.serverId),L.stackName].includes(R))throw Error(`Refusing to optimize ${R}: project state is pinned to ${L.serverName}.`);let z=St(m),Y=new Oe({apiToken:Cr(z.apiToken,m)}),Z=await Y.getServer(L.serverId),X=L.publicIp??Z.public_net.ipv4?.ip;if(!X)throw Error(`Server ${Z.name} has no public IPv4 address.`);let ne=Co(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:Z.name,plan:ne},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[Z.name,ne.firewallPorts.join(","),ne.monitoring?"on":"off",ne.autoUpdates?"on":"off",`${ne.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${Z.name} to execute.`);return}if(t.confirm!==Z.name)throw Error(`Optimization requires --confirm ${Z.name}.`);let ie={host:X,user:L.sshUser??z.sshUser,identityFile:z.sshPrivateKeyPath,connectTimeoutSec:15},se=await un(ie),be=se.routeProbes.filter((nt)=>!nt.ok),Ae=m.infrastructure?.compute,le=te(Ae)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,ke=se.failedUnits.filter((nt)=>!le.has(nt));if(ke.length>0)throw Error(`Preflight found failed services: ${ke.join(", ")}`);if(be.length>0)throw Error(`Preflight found unhealthy routes: ${be.map((nt)=>nt.domain).join(", ")}`);let De=te(Ae)?[]:Object.values(m.sites??{}).flatMap((nt)=>typeof nt?.port==="number"&&![80,443].includes(nt.port)?[nt.port]:[]),Se=dn({allowSsh:Ae?.allowSsh!==!1,sitePorts:De,allowedPorts:Ae?.firewall?.allowedPorts}),Re=(L.firewallId?(await Y.listFirewalls()).find((nt)=>nt.id===L.firewallId):void 0)??(await Y.listFirewalls()).find((nt)=>nt.name===`${m.project.slug}-${k}-app-fw`);if(!Re)throw Error(`Managed firewall for ${Z.name} was not found.`);let Pe=await Y.setFirewallRules(Re.id,Se);await Promise.all(Pe.map((nt)=>Y.waitForAction(nt.id))),await xs(m,ie);let[ze,Le]=await Promise.all([un(ie),_s(ie)]),Be=Os(ne,Le),Ve=zc(se,ze),ct=ze.routeProbes.filter((nt)=>!nt.ok);if(Ve.stoppedServices.length>0)Be.push(`services stopped: ${Ve.stoppedServices.join(", ")}`);if(Ve.changedRouteFragments.length>0)Be.push(`route fragments changed: ${Ve.changedRouteFragments.join(", ")}`);if(Ve.missingRouteIds.length>0)Be.push(`routes disappeared: ${Ve.missingRouteIds.join(", ")}`);if(Ve.changedReleaseLinks.length>0)Be.push(`release links changed: ${Ve.changedReleaseLinks.join(", ")}`);if(Ve.missingData.length>0)Be.push(`databases or volumes disappeared: ${Ve.missingData.join(", ")}`);if(ct.length>0)Be.push(`unhealthy routes: ${ct.map((nt)=>nt.domain).join(", ")}`);if(Be.length>0)throw Error(`Host optimization verification failed: ${Be.join("; ")}`);let Dt={serverId:Z.id,serverName:Z.name,services:ze.runningServices.length,routes:ze.routeIds.length,healthyDomains:ze.routeProbes.length,releaseLinks:ze.releaseLinks.length,databasesAndVolumes:ze.dataCatalog.length,report:Le};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:Dt},null,2));else n(`${Z.name} passed full host, rpx route, service, release, and data verification.`)}async function $p(R,t,m){let k=await Ne(),I=m.env??"production",L=T(k,I);await bi(async(z)=>{let Y=Wi(z,R),Z=z.store.list(z.controlPlane.project.id,!0),X=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let Re=St(k);return new Oe({apiToken:Cr(Re.apiToken,k)})}catch{return null}})():null,ne=Y.providerId?Number(Y.providerId):Number.NaN,ie=await ge(L),se=ie!=null&&ie.serverId===ne,be=new qr,Ae=Y.trustState==="pinned",le={takenNames:async()=>{let Re=Z.map((Pe)=>Pe.name);if(X)Re.push(...(await X.listServers()).map((Pe)=>Pe.name));return Re},inventoryName:()=>z.store.get(Y.id)?.name??Y.name,renameInventory:(Re)=>{z.store.update(Y.id,{name:Re})},...X&&Number.isFinite(ne)?{providerName:async()=>(await X.getServer(ne)).name,renameProvider:async(Re)=>{await X.renameServer(ne,Re)}}:{},...se?{stateName:async()=>(await ge(L))?.serverName,writeStateName:async(Re)=>{let Pe=await ge(L);if(Pe)await vt(L,{...Pe,serverName:Re})}}:{},...Ae?{remoteHostname:async()=>{let Re=await be.exec(Y,"hostname");return Re.code===0?Re.stdout.trim():void 0},setRemoteHostname:async(Re)=>{let Pe=await be.exec(Y,bd(Re));if(Pe.code!==0)throw Error(Pe.stderr.trim()||`hostname exited ${Pe.code}`)}}:{}},ke=await vd(Y.name,t,le),De=await zs(ke);if(!m.apply){let Re=[X?"":"provider record (no provider id or no API token)",se?"":"local state pin (none points at this server)",Ae?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:ke.operation,target:ke.target,rename:{from:Y.name,to:t},notCovered:Re,steps:De.map((Pe)=>({id:Pe.step.id,title:Pe.step.title,state:Pe.state,change:Pe.step.change,reason:Pe.reason}))},null,2));return}for(let Pe of Us(ke,De))console.log(Pe);for(let Pe of Re)console.log(` not covered: ${Pe}`);console.log(" Re-run with --apply to perform it.");return}let Se=await Ws(ke,De,{log:(Re)=>e(Re),audit:(Re)=>z.controlPlane.store.appendEvent({projectId:z.controlPlane.project.id,resourceId:Y.resourceId,type:`${Re.operation}.${Re.step}.${Re.state}`,level:Re.state==="failed"?"error":"info",payload:{target:Re.target,renameTo:t,...Re.error?{error:Re.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Se},null,2));if(!Se.success){let Re=Se.steps.find((Pe)=>Pe.state==="failed");throw Error(`${ke.operation} stopped at '${Re?.title}': ${Re?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function ec(R){R.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await bi(async(k)=>{let I=t?[Wi(k,t)]:k.store.list(k.controlPlane.project.id),L=I.flatMap((z)=>Object.entries(z.capabilities).map(([Y,Z])=>({server:z.name,provider:z.provider,action:Y,...Z})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:L},null,2));else c(["Server","Provider","Action","Support","Explanation"],L.map((z)=>[z.server,z.provider,z.action,z.supported?"supported":"unsupported",z.reason??"—"]))})}catch(k){kn(k)}}),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(t,m,k)=>{try{await Sp(t,m,k)}catch(I){kn(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(t,m)=>{try{await Cp(t,m)}catch(k){kn(k)}}),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(t,m)=>{try{await bp(t,m)}catch(k){kn(k)}}),R.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await bi(async(m)=>{let k=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],k.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(m){kn(m)}}),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(t,m)=>{try{await bi(async(k)=>{let I=m.provider;if(!["aws","hetzner","ssh"].includes(I)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let L=k.service.enroll({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,provider:I,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((z)=>z.split("=")).filter((z)=>z[0]&&z[1]))});n(`Enrolled ${L.name} as ${L.id}; no remote mutation was performed.`)})}catch(k){kn(k)}}),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(t,m)=>{try{await bi(async(k)=>{let I=Wi(k,t);if(I=await k.service.test(I.id),I.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${I.pendingHostKey}; review it first.`);I=k.service.reviewHostKey(I.id,m.acceptHostKey)}let L=await k.service.validate(I.id);if(m.json)console.log(JSON.stringify(L.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(L.validation?.findings??[]).map((z)=>[z.severity,z.code,z.message,z.remediation??"—"]));if(!L.validation?.valid)process.exitCode=1})}catch(k){kn(k)}}),R.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await bi(async(k)=>{let I=k.service.bootstrap(Wi(k,t).id,!!m.apply);if(I.preview)c(["Step"],I.steps.map((L)=>[L]));else n(`Bootstrap queued: ${I.operation?.id}`)})}catch(k){kn(k)}}),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(t,m,k)=>{try{await $p(t,m,k)}catch(I){kn(I)}}),R.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await bi(async(k)=>n(k.service.drain(Wi(k,t).id,!!m.complete).status))}catch(k){kn(k)}}),R.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await bi(async(m)=>{m.service.uncordon(Wi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){kn(m)}}),R.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await bi(async(k)=>{k.service.archive(Wi(k,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(k){kn(k)}}),R.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await bi(async(m)=>{let k=Wi(m,t);if(k.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let I=Bun.spawn(["ssh","-p",String(k.sshPort),"-o","StrictHostKeyChecking=yes",`${k.sshUser}@${k.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),L=await I.exited;if(L)process.exitCode=L})}catch(m){kn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])R.command(t,m).action(async(...k)=>En(t.split(" ")[0],{target:String(k[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as Sd,mkdirSync as kp,readFileSync as Ap,writeFileSync as Rp}from"node:fs";import{join as Cd,resolve as Ip}from"node:path";var tc=(R)=>{r(R instanceof Error?R.message:String(R)),process.exitCode=1};async function Pp(){try{return await Ne()}catch{return}}function xp(R){if(R===void 0)return;let t=Number(R);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${R}'.`);return t}function $d(R,t,m){let k=R?.ssh?.hosts?.find((I)=>I.host===t);return new Ir({hosts:t?[k??{host:t}]:R?.ssh?.hosts,user:m.user,port:xp(m.port),privateKeyPath:m.key,hostKey:R?.ssh?.hostKey,sudo:R?.ssh?.sudo,profile:m.profile??R?.ssh?.profile,publicIp:R?.ssh?.publicIp,lan:R?.ssh?.lan})}var kd=1073741824;function nc(R){R.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let k=await Pp(),I=$d(k,t,m),L=t??I.targetHost(),z=await I.ensureHostKey(L),{facts:Y,findings:Z}=await I.preflight(L);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:L,hostKeyFingerprint:z.fingerprint,facts:Y,findings:Z},null,2));else{if(i(`Preflight ${L}`),z.pinnedNow)e(`Pinned host key ${z.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/kd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/kd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(pn(Z)),Rr(Z))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(Rr(Z))process.exitCode=1}catch(k){tc(k)}}),R.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await Ne(),k=t.env??"production";if(t.dryRun){let z=Ar(m),[Y]=z.hosts;console.log(wr({config:m,environment:k,profile:z.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:z.lan}));return}let I=$d(m,void 0,{});i(`Adopt ${I.targetHost()}`);let L=await I.provisionComputeInfrastructure({config:m,environment:k});n(`${L.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${k}`)}catch(m){tc(m)}}),R.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in So))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let k=await Ne(),I=t.env??"production",L=Ar(k,{hosts:k.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),z=t.user??(k.ssh?.hosts?.[0]?.user??"pi"),Y=ln(t.key??"~/.ssh/id_ed25519.pub");if(!Sd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let Z=Ap(Y,"utf8").trim(),X;if(t.wifiSsid){let Ae=t.wifiPassphraseEnv??"WIFI_PASSWORD",le=process.env[Ae];if(!le)throw Error(`--wifi-ssid needs the passphrase in $${Ae} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");X={ssid:t.wifiSsid,passphrase:le,country:t.wifiCountry}}let ne=wr({config:k,environment:I,profile:L.profile,sudoUser:z!=="root"?z:void 0,lan:L.lan}),ie=vo({hostname:t.hostname,user:z,publicKey:Z,timezone:t.timezone,locale:t.locale,wifi:X},ne,{os:m}),se=Ip(t.out);kp(se,{recursive:!0});let be=Object.keys(ie.files).filter((Ae)=>Sd(Cd(se,Ae)));if(be.length>0&&!t.force)throw Error(`${be.join(", ")} already exist in ${se}; pass --force to overwrite.`);for(let[Ae,le]of Object.entries(ie.files))Rp(Cd(se,Ae),le,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(ie.files).join(", ")} to ${se}`),console.log(ie.instructions)}catch(m){tc(m)}})}async function Dp(){let R=await Ne(),t=y(process.cwd(),R),m=new Bn(t.store),k=new jn(m,new xe(t.store));return{controlPlane:t,store:m,service:k}}async function as(R){let t=await Dp();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Vs=(R)=>Object.fromEntries(String(R??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Ad=(R)=>Object.fromEntries(Object.entries(Vs(R)).map(([t,m])=>[t,Number(m)]));function rc(R){R.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>as((m)=>{let k=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],k.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(t,m)=>as((k)=>{let{purpose:I,backend:L}=m;if(!["application","build","worker","monitoring","backup"].includes(I)||!["server","ecs","asg"].includes(L))throw Error("Unsupported pool purpose or backend.");let z=k.store.createPool({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,purpose:I,backend:L,region:m.region,architecture:m.arch,labels:Vs(m.labels),requiredServerLabels:Vs(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Ad(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${z.name} (${z.id}).`)})),R.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>as((k)=>{let I=k.store.listPools(k.controlPlane.project.id).find((z)=>z.id===t||z.name===t),L=new xe(k.controlPlane.store).list(k.controlPlane.project.id).find((z)=>z.id===m||z.name===m);if(!I||!L)throw Error("Pool or server was not found.");k.store.addMember(I.id,L.id),n(`Attached ${L.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(t)=>as((m)=>{let k=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Ad(t.resources),region:t.region,architecture:t.arch,labels:Vs(t.labels)});if(t.json)console.log(JSON.stringify(k,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],k.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(t)=>as((m)=>{let k=m.store.listPools(m.controlPlane.project.id).find((L)=>L.id===t||L.name===t);if(!k)throw Error("Pool was not found.");let I=m.service.drainPool(k.id);n(`Draining ${k.name}: moved ${I.moved.length}, blocked ${I.blocked.length} stateful placement(s).`)}))}async function Ep(){let R=await Ne(),t=y(process.cwd(),R),m=new Vn(t.store),k=new zn(m);return{controlPlane:t,store:m,service:k}}async function ro(R){let t=await Ep();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var cs=(R,t)=>{let m=R.store.list(R.controlPlane.project.id).find((k)=>k.id===t||k.name===t);if(!m)throw Error("Regional topology was not found.");return m},Tp=(R)=>R.split(",").map((t,m)=>{let[k,I="aws"]=t.split(":");return{region:String(k),provider:I,role:m===0?"primary":"secondary"}}),Np=(R)=>{let t=new Set(["s3","dynamodb","secrets"]),m=R.split(",").map((I)=>I.trim()),k=m.find((I)=>!t.has(I));if(k)throw Error(`Unsupported replication kind: ${k}`);return m};function ic(R){R.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>ro((m)=>{let k=m.store.list(m.controlPlane.project.id).map((I)=>({topology:I,targets:m.store.targets(I.id),channels:m.store.channels(I.id),route:m.store.route(I.id),executions:m.store.executions(I.id)}));if(t.json)console.log(JSON.stringify(k,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],k.map((I)=>[I.topology.name,I.topology.hostname,I.topology.activeRegion,I.topology.status,I.topology.revision??"—",`${I.channels.filter((L)=>L.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(t,m)=>ro((k)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let I=k.service.create({organizationId:k.controlPlane.organization.id,projectId:k.controlPlane.project.id,name:t,hostname:m.hostname,regions:Tp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Np(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`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(t,m,k)=>ro((I)=>c(["Step"],I.service.plan(cs(I,t).id,m,k.target).map((L)=>[L])))),R.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,k)=>ro(async(I)=>{let L=k.manifest?await Bun.file(k.manifest).json():{},z=I.service.enqueue({topologyId:cs(I,t).id,kind:"rollout",revision:m,manifest:L});n(`Regional rollout queued: ${z.operation.id}`)})),R.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${I.operation.id}`)})),R.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"failback",targetRegion:m});n(`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(t,m)=>ro((k)=>{let I=k.service.enqueue({topologyId:cs(k,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${I.operation.id}; replicated data remains retained.`)}))}var ls="0.16.83";async function Lp(){let R=await Ne(),t=y(process.cwd(),R),m=new Hn(t.store),k=new Gn(m),I=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((L)=>new qn(L,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:k,cleanup:I}}async function Ii(R){let t=await Lp();try{await R(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function oc(R){R.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>Ii((m)=>{let k={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},I=[...k.manifests.map((L)=>["update",L.version,L.compatibility.compatible?"compatible":"blocked",L.compatibility.reasons.join("; ")||L.channel]),...k.campaigns.map((L)=>["upgrade",L.id,L.status,L.currentStage??L.fromVersion]),...k.cleanups.map((L)=>["cleanup",L.kind,L.status,`${L.candidates.length} items / ${L.estimatedBytes} bytes`]),...k.drills.map((L)=>["DR drill",L.scenario,L.status,L.isolatedTarget])];if(t.json)console.log(JSON.stringify(k,null,2));else c(["Area","Name / version","Status","Detail"],I)})),R.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>Ii(async(k)=>{let I=k.store.addTrustedKey({organizationId:k.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${I.name}: ${I.fingerprint}`)})),R.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,k)=>Ii(async(I)=>{let L=await Bun.file(t).json(),z=(await Bun.file(m).text()).trim(),Y=I.store.importManifest({organizationId:I.controlPlane.organization.id,keyId:k,document:L,signature:z,current:{schemaVersion:I.controlPlane.store.health().schemaVersion,currentVersion:ls,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.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(t,m,k)=>Ii((I)=>{let L=I.store.createWindow({projectId:I.controlPlane.project.id,name:t,schedule:m,timezone:k.timezone,durationMinutes:Number(k.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${L.name} (${L.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(t,m,k)=>Ii((I)=>{let L=new xe(I.controlPlane.store).list(I.controlPlane.project.id).filter((Z)=>Z.status==="ready").map((Z)=>({serverId:Z.id,target:Z.name,previousVersion:Z.bootstrapVersion??ls}));if(!L.length)L.push({target:"control-plane",previousVersion:ls});let z=I.store.createCampaign({projectId:I.controlPlane.project.id,manifestId:t,fromVersion:ls,strategy:k.strategy==="rolling"?"rolling":"canary",batchSize:Number(k.batch),healthGate:{kind:"platform"},backupId:m,targets:L}),Y=I.service.enqueueCampaign(z.id);n(`Staged upgrade queued: ${Y.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(t,m)=>Ii(async(k)=>{let I=await k.service.previewCleanup({projectId:k.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},k.cleanup);c(["ID","Candidate","Bytes"],I.candidates.map((L)=>[L.id,L.label,String(L.bytes)])),e(`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(t,m)=>Ii((k)=>{let I=k.service.enqueueCleanup(t,String(m.confirm??""));n(`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(t,m,k)=>Ii((I)=>{let L=I.store.createDrill({projectId:I.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(k.rpo),expectedRtoMinutes:Number(k.rto),recoveryPointId:k.recoveryPoint,topologyId:k.topology});n(`Planned isolated drill ${L.id}.`)})),R.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>Ii((m)=>{let k=m.service.enqueueDrill(t);n(`DR drill queued: ${k.operation.id}`)}))}async function sc(){try{return(await Ne()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function ac(R){R.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await sc(),k=new D(m);try{let{Functions:I=[]}=await k.listFunctions({MaxItems:50});if(!I.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],I.map((L)=>[L.FunctionName??"-",L.Runtime??"-",L.MemorySize?`${L.MemorySize} MB`:"-",L.Timeout?`${L.Timeout}s`:"-",L.LastModified??"-"]))}catch(I){r(`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(t,m)=>{i(`Invoking ${t}`);let k=m?.region||await sc(),I=new D(k),L=new s("Invoking function...");L.start();try{let z=await I.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(z.FunctionError){if(L.fail(`Function returned an error (${z.FunctionError})`),z.Payload)e(z.Payload);process.exitCode=1;return}if(L.succeed(`Invoked (status ${z.StatusCode})`),z.Payload)e(`
319
319
  Response:`),e(z.Payload);if(z.LogResult)e(`
320
320
  Logs:`),e(Buffer.from(z.LogResult,"base64").toString("utf-8"))}catch(z){L.fail(`Invocation failed: ${z.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(t,m)=>{i(`Logs for ${t}`);let k=m?.region||await sc(),I=new ae(k),L=t.startsWith("/aws/lambda/")?t:`/aws/lambda/${t}`,z=Number(m?.since??15),Y=(Z)=>{for(let X of Z){let ne=X.timestamp?new Date(X.timestamp).toISOString():"";e(`${ne} ${(X.message??"").trimEnd()}`)}};try{let Z=Date.now()-z*60000,{events:X=[]}=await I.filterLogEvents({logGroupName:L,startTime:Z,filterPattern:m?.filter,limit:200});if(Y(X),X.length)Z=(X[X.length-1].timestamp??Z)+1;if(m?.tail){e(`
321
321
  (streaming — Ctrl+C to stop)`);for(;;){await new Promise((ie)=>setTimeout(ie,3000));let{events:ne=[]}=await I.filterLogEvents({logGroupName:L,startTime:Z,filterPattern:m?.filter,limit:200});if(ne.length)Y(ne),Z=(ne[ne.length-1].timestamp??Z)+1}}}catch(Z){r(`Failed to read logs: ${Z.message}`),process.exitCode=1}})}async function Rd(R){let t=Bun.spawn(["docker",...R],{stdin:"inherit",stdout:"inherit",stderr:"pipe"}),[m,k]=await Promise.all([t.exited,new Response(t.stderr).text()]);return{ok:m===0,exitCode:m,command:["docker",...R].join(" "),stderr:k.trim()}}function cc(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(t)=>{let m=["build","--file",t.file??"Dockerfile","--tag",t.tag??"latest","."];if(t.dryRun){console.log(`docker ${m.join(" ")}`);return}let k=await Rd(m);if(t.json)console.log(JSON.stringify(k));if(!k.ok)r(k.stderr||`docker exited ${k.exitCode}`),process.exitCode=k.exitCode;else n(`Built ${t.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(t)=>{if(!t.image){r("--image with a full registry reference is required; credentials must come from docker credential helpers."),process.exitCode=2;return}if(t.dryRun){console.log(`docker push ${t.image}`);return}let m=await Rd(["push",t.image]);if(t.json)console.log(JSON.stringify(m));if(!m.ok)r(m.stderr),process.exitCode=m.exitCode;else n(`Pushed ${t.image}.`)}),R.command("container:deploy","Deploy a container image").action(async()=>En("container:deploy",{message:"Direct ECS mutation is not registered as a shared release driver.",nextAction:"Import the image as an application and use the immutable release deployment workflow."}))}function lc(R){R.command("domain:list","List all domains").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t)=>{i("Domains");try{let m=Vr(t?.provider),k=bn(t?.provider)?.provider||"unknown",I=new s(`Fetching domains from ${k}...`);I.start();let L=await m.listDomains();if(I.succeed(`Found ${L.length} domain(s)`),L.length===0){e("No domains found in this provider");return}let z=L.map((Y)=>[Y,"Active","-",k.charAt(0).toUpperCase()+k.slice(1)]);c(["Domain","Status","SSL","Provider"],z)}catch(m){r(`Failed to list domains: ${m instanceof Error?m.message:String(m)}`)}}),R.command("domain:add <domain>","Add a new domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t,m)=>{i(`Adding Domain: ${t}`);try{let k=Vr(m?.provider),I=bn(m?.provider)?.provider||"unknown",L=new s(`Checking if ${I} can manage ${t}...`);if(L.start(),await k.canManageDomain(t))L.succeed(`Domain ${t} is already available in ${I}`),e(`
@@ -372,7 +372,7 @@ Deployment complete!`),e(`Total size: ${be} MB`),e(`
372
372
  Assets URL: https://${L}.s3.${k}.amazonaws.com${z?`/${z}`:""}`)}catch(m){r(`Deployment failed: ${m.message}`)}}),R.command("assets:invalidate","Invalidate CloudFront cache").option("--distribution <id>","CloudFront distribution ID").option("--paths <paths>","Paths to invalidate (comma-separated)",{default:"/*"}).option("--wait","Wait for invalidation to complete").action(async(t)=>{i("Invalidating CloudFront Cache");try{let m=t?.distribution;if(!m){r("--distribution is required");return}let I=(t?.paths||"/*").split(",").map((ne)=>ne.trim()),L=t?.wait||!1;if(e(`Distribution: ${m}`),e(`Paths: ${I.join(", ")}`),!await d(`
373
373
  Invalidate cache now?`,!0)){e("Invalidation cancelled");return}let Y=new E,Z=new s("Creating invalidation...");Z.start();let X=await Y.invalidatePaths(m,I);if(Z.succeed("Invalidation created"),n(`
374
374
  Invalidation ID: ${X.Id}`),e(`Status: ${X.Status}`),e(`Created: ${new Date(X.CreateTime).toLocaleString()}`),L){let ne=new s("Waiting for invalidation to complete...");ne.start(),await Y.waitForInvalidation(m,X.Id),ne.succeed("Invalidation completed!")}else e(`
375
- Invalidation is in progress. Use --wait to wait for completion.`)}catch(m){r(`Invalidation failed: ${m.message}`)}})}function qc(R){for(let[t,m]of[["team:add <email> <role>","Invite an organization member"],["team:list","List organization members"],["team:remove <email>","Revoke organization membership"]])R.command(t,m).action(async(...k)=>En(t.split(" ")[0],{target:String(k[0]??""),message:"Legacy IAM-backed team commands are deprecated and cannot safely represent organization-scoped access.",nextAction:"Use the Team dashboard or organization invitation API; this command exits without changing IAM."}))}import{execFileSync as Yf,execSync as dl}from"node:child_process";import{copyFileSync as As,existsSync as In,mkdirSync as au,readFileSync as ll,writeFileSync as Zf}from"node:fs";import{tmpdir as cu}from"node:os";import{dirname as Qf,join as lu,resolve as Xf}from"node:path";import{existsSync as Hc,readdirSync as Vd,statSync as Gc}from"node:fs";import{join as ea}from"node:path";var pf=new Set([".DS_Store","Thumbs.db",".gitkeep",".keep"]);function qd(R){return pf.has(R)}function Hd(R,t=0){if(t>8)return!0;let m;try{m=Vd(R)}catch{return!1}for(let k of m){if(qd(k))continue;let I=ea(R,k),L;try{L=Gc(I)}catch{continue}if(L.isFile())return!0;if(L.isDirectory()&&Hd(I,t+1))return!0}return!1}function ff(R){let t;try{t=Vd(R)}catch{return[]}let m=[];for(let k of t){if(qd(k))continue;let I=ea(R,k);try{if(Gc(I).isDirectory()&&Hc(ea(I,"index.html")))m.push(k)}catch{}}return m.sort((k,I)=>k.localeCompare(I))}function Gd(R){let{root:t,siteName:m,expectIndex:k}=R,I=[];if(!Hc(t))return I.push({level:"error",message:`Build output not found at ${t} for site '${m}'`}),I;if(!Gc(t).isDirectory())return I.push({level:"error",message:`Site '${m}' has root ${t}, which is a file, not a directory`}),I;if(!Hd(t))return I.push({level:"error",message:`Site '${m}' would ship an empty release: ${t} contains no files. Check that the build ran and wrote where 'root' points.`}),I;if(!k)return I;if(Hc(ea(t,"index.html")))return I;let L=ff(t);if(L.length===1){let z=`${t.replace(/\/+$/,"")}/${L[0]}`;return I.push({level:"error",message:`Site '${m}' has no index.html at the top of ${t}, but ${z} has one. The generator wrote one level down, so this release would serve 404s at the domain root. Set root: '${z}'.`}),I}if(L.length>1)return I.push({level:"warning",message:`Site '${m}' has no index.html at the top of ${t}. These subdirectories have one: ${L.join(", ")}. The domain root will 404.`}),I;return I.push({level:"warning",message:`Site '${m}' has no index.html anywhere under ${t}. The domain root will 404.`}),I}function gf(R){if(!R)return[];if(Array.isArray(R))return R.map(String);let t=R,m=t.Items??t.Item;if(!m)return[];if(Array.isArray(m))return m.map(String);if(typeof m==="object"&&m!==null){let k=m;if("Item"in k){let I=k.Item;if(!I)return[];return Array.isArray(I)?I.map(String):[String(I)]}if("CNAME"in k){let I=k.CNAME;if(!I)return[];return Array.isArray(I)?I.map(String):[String(I)]}return Object.values(k).flatMap((I)=>{if(Array.isArray(I))return I.map(String);return typeof I==="string"?[I]:[]})}return[String(m)]}async function ta(R){if(R.length===0)return;let t=new E,m=await t.listDistributions(),k=[...new Set(R.map((I)=>I.toLowerCase()))];for(let I of k){let L=m.find((Y)=>gf(Y.Aliases).some((X)=>X.toLowerCase()===I));if(!L?.Id){a(`No CloudFront distribution found for ${I} — skipping dynamic HTTP method sync`);continue}if(await t.ensureDynamicHttpMethods(L.Id))n(`CloudFront ${L.Id} (${I}): enabled POST/PUT/PATCH/DELETE on dynamic paths`);else e(`CloudFront ${L.Id} (${I}): already allows dynamic HTTP methods`)}}import{execSync as hf}from"node:child_process";async function yf(R,t,m,k={},I=process.cwd()){if(!R)return;if(k.step?.(`Running ${m} hook`),typeof R==="string"){hf(R,{stdio:"inherit",cwd:I});return}await R(t)}async function vs(R,t,m={},k){try{return await yf(R.hooks?.[t],R,t,m,k),!0}catch(I){return m.error?.(`${t} hook failed: ${I?.message||I}`),!1}}var Si=(R)=>R===void 0?void 0:R?"on":"off";function Jc(R){let t={ssl:R.ssl,always_use_https:Si(R.alwaysUseHttps),automatic_https_rewrites:Si(R.automaticHttpsRewrites),min_tls_version:R.minTlsVersion,tls_1_3:Si(R.tls13),brotli:Si(R.brotli),http3:Si(R.http3),"0rtt":Si(R.zeroRtt),early_hints:Si(R.earlyHints),browser_cache_ttl:R.browserCacheTtl,always_online:Si(R.alwaysOnline),websockets:Si(R.websockets),email_obfuscation:Si(R.emailObfuscation)};if(R.hsts)t.security_header={strict_transport_security:{enabled:R.hsts.enabled,max_age:R.hsts.maxAge??31536000,include_subdomains:R.hsts.includeSubdomains??!1,preload:R.hsts.preload??!1,nosniff:R.hsts.noSniff??!0}};for(let m of Object.keys(t))if(t[m]===void 0)delete t[m];return{...t,...R.raw??{}}}var bs={ssl:"strict",alwaysUseHttps:!0,automaticHttpsRewrites:!0,minTlsVersion:"1.2",tls13:!0,brotli:!0,http3:!0,earlyHints:!0,alwaysOnline:!0,emailObfuscation:!1,browserCacheTtl:0};import{connect as vf}from"node:tls";async function Yc(R){let{address:t,serverName:m,port:k=443,timeoutMs:I=5000}=R;return new Promise((L)=>{let z=!1,Y=(X)=>{if(z)return;z=!0;try{Z.destroy()}catch{}L(X)},Z=vf({host:t,port:k,servername:m,rejectUnauthorized:!1,timeout:I});Z.once("secureConnect",()=>{if(Z.authorized){Y({reachable:!0,trusted:!0});return}Y({reachable:!0,trusted:!1,reason:Z.authorizationError?String(Z.authorizationError):"origin certificate is not trusted for this hostname"})}),Z.once("timeout",()=>{Y({reachable:!1,trusted:!1,reason:`no TLS handshake within ${I}ms`})}),Z.once("error",(X)=>{Y({reachable:!1,trusted:!1,reason:X.message})})})}function bf(R,t){let m=t.replace(/\.$/,"").toLowerCase();return R.some((k)=>{let I=k.replace(/\.$/,"").toLowerCase();if(I===m)return!0;if(!I.startsWith("*."))return!1;let L=I.slice(2);if(!m.endsWith(`.${L}`))return!1;return!m.slice(0,m.length-L.length-1).includes(".")})}async function Zc(R){let{provider:t,zone:m,hosts:k,ipv4:I,ipv6:L,proxied:z=!0,settings:Y=bs,cache:Z,originGuard:X,purge:ne=!0,ttl:ie=300,skipOriginProbe:se=!1,skipEdgeCertificateCheck:be=!1}=R,Ae={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(k.length===0)return Ae;let le=[],ke=z&&!be?await t.listEdgeCertificateHosts(m):null;for(let Se of k){let Re=z;if(Re&&ke&&!bf(ke,Se)){Re=!1;let ze=ke.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${ke.join(", ")})`;Ae.deferredProxy.push({host:Se,reason:ze}),Ae.warnings.push(`${Se}: publishing DNS-only — ${ze}. Proxying it would make Cloudflare terminate TLS with no certificate for the name, which fails the handshake outright rather than degrading. Universal SSL covers the apex and ONE level of subdomain, so a deeper name needs its own certificate; otherwise re-run the deploy once the certificate is active.`)}if(Re&&!se){let ze=await Yc({address:I,serverName:Se});if(!ze.trusted){Re=!1;let Le=ze.reason||"origin is not serving a trusted certificate";Ae.deferredProxy.push({host:Se,reason:Le}),Ae.warnings.push(`${Se}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${Le}). The origin issues certificates over HTTP-01, which needs the name to reach it directly; re-run the deploy once it has one and the record will be proxied.`)}}if(Re)le.push(Se);let Pe=[{type:"A",content:I}];if(L&&mo(Se))Pe.push({type:"AAAA",content:L});for(let{type:ze,content:Le}of Pe){let Be=await t.upsertRecord(m,{name:Se,type:ze,content:Le,ttl:ie,proxied:Re});if(Be.success)Ae.records.push({host:Se,type:ze,content:Le,proxied:Re});else Ae.warnings.push(`${Se} ${ze} → ${Le} failed: ${Be.message||"unknown provider error"}`)}}if(le.length===0){if(z)Ae.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return Ae}try{let Se=Jc(Y),Re=await t.applyZoneSettings(m,Se);Ae.settingsChanged=Re.changed;for(let Pe of Re.failed)Ae.warnings.push(`zone setting '${Pe.id}' could not be applied: ${Pe.error}`)}catch(Se){Ae.warnings.push(`zone settings could not be read: ${Se instanceof Error?Se.message:String(Se)}`)}let De=Qs(le,Z);if(De.length>0){let Se=await t.putManagedPhaseRules(m,"http_request_cache_settings",De);if(Se.success)Ae.cacheRules=De.length;else Ae.warnings.push(`cache rules could not be written: ${Se.message}`)}if(X){let Se=Ys(le,X.header,X.value);if(Se.length>0){let Re=await t.putManagedPhaseRules(m,"http_request_late_transform",Se);if(Re.success)Ae.originGuard=!0;else Ae.warnings.push(`origin guard header could not be written: ${Re.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(ne){if(Ae.purged=await t.purgeCache(m,{hosts:le}),!Ae.purged)Ae.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return Ae}var wf=(R)=>process.env[R];function Kd(R,t){let m=R.replace(/\.$/,"").toLowerCase();if(t){let k=t.replace(/\.$/,"").toLowerCase();if(m===k||m.endsWith(`.${k}`))return k}return m.split(".").slice(-2).join(".")}function Qc(R,t={}){let m=t.env??wf,k=R.infrastructure?.compute?.proxy?.cdn,I=[];if(!k||k.provider!=="cloudflare")return{plan:null,errors:I};if(k.originDomain)I.push(`compute.proxy.cdn.originDomain (${k.originDomain}) is ignored for Cloudflare: the proxy forwards to the address in the record it fronts, `+"so no separate origin hostname is needed — and publishing one gives clients a documented way around the edge.");let L=m("CLOUDFLARE_API_TOKEN");if(!L)return I.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:I};let z=R.sites??{},Y=k.frontedHosts?.length?[...new Set(k.frontedHosts.map((se)=>se.toLowerCase()))]:ho(z,{autoWww:R.infrastructure?.compute?.proxy?.autoWww!==!1});if(Y.length===0)return I.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:I};let Z=R.infrastructure?.dns?.domain,X=new Set(Y.map((se)=>Kd(se,Z)));if(X.size>1)return I.push(`Fronted hosts span more than one zone (${[...X].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:I};let ne=k.cloudflare??{},ie=k.secret?{header:k.secretHeader??"X-Origin-Verify",value:k.secret}:void 0;return{plan:{zone:[...X][0],hosts:Y,apiToken:L,zoneId:ne.zoneId??m("CLOUDFLARE_ZONE_ID"),accountId:ne.accountId??m("CLOUDFLARE_ACCOUNT_ID"),proxied:ne.proxied!==!1,settings:ne.settings??bs,cache:ne.cache,originGuard:ie,purge:ne.purgeOnDeploy!==!1,skipOriginProbe:ne.skipOriginProbe===!0},errors:I}}var Sf="https://api.cloudflare.com/client/v4",Yd=10042,Cf=10006,$f=10059;class co extends Error{status;errors;constructor(R,t,m=[]){super(R);this.name="R2ApiError",this.status=t,this.errors=m}hasCode(R){return this.errors.some((t)=>t.code===R)}}class Hi extends co{accountId;constructor(R,t,m=[]){super(`R2 is not enabled on Cloudflare account ${R}. Enable it once in the Cloudflare dashboard (R2 Object Storage, then follow the prompt to activate it), then re-run the deploy.`,t,m);this.name="R2NotEnabledError",this.accountId=R}}class Oo{name="cloudflare-r2";apiToken;accountId;fetchImpl;constructor(R){if(!R.apiToken)throw Error("Cloudflare R2 needs an API token");if(!R.accountId)throw Error("Cloudflare R2 needs an account id");this.apiToken=R.apiToken,this.accountId=R.accountId,this.fetchImpl=R.fetch??((t,m)=>fetch(t,m))}async requestEnvelope(R,t,m,k={}){let I={Authorization:`Bearer ${this.apiToken}`};if(m!==void 0)I["Content-Type"]="application/json";if(k.jurisdiction&&k.jurisdiction!=="default")I["cf-r2-jurisdiction"]=k.jurisdiction;let L=await this.fetchImpl(`${Sf}/accounts/${this.accountId}/r2${t}`,{method:R,headers:I,body:m===void 0?void 0:JSON.stringify(m)}),z=await L.text(),Y;try{Y=JSON.parse(z)}catch{throw new co(`Cloudflare R2 API returned ${L.status} with a non-JSON body: ${z.slice(0,200)}`,L.status)}if(!Y.success){let Z=Y.errors??[];if(Z.some((ne)=>ne.code===Yd))throw new Hi(this.accountId,L.status,Z);let X=Z.map((ne)=>`${ne.code}: ${ne.message}`).join(", ");throw new co(`Cloudflare R2 API error (${L.status}) on ${R} ${t}: ${X||z.slice(0,200)}`,L.status,Z)}return Y}async request(R,t,m,k){return(await this.requestEnvelope(R,t,m,k)).result}bucketPath(R){return`/buckets/${encodeURIComponent(R)}`}async listBuckets(R={}){let t=[],m;do{let k=new URLSearchParams({per_page:"1000"});if(m)k.set("cursor",m);let I=await this.requestEnvelope("GET",`/buckets?${k}`,void 0,R),L=I.result?.buckets??[];t.push(...L),m=L.length>0?I.result_info?.cursor||void 0:void 0}while(m);return t}async getBucket(R,t={}){try{return await this.request("GET",this.bucketPath(R),void 0,t)}catch(m){if(m instanceof Hi)throw m;if(m instanceof co&&(m.hasCode(Cf)||m.status===404))return null;throw m}}async ensureBucket(R,t={}){let m={jurisdiction:t.jurisdiction},k=await this.getBucket(R,m);if(k)return{bucket:k,created:!1};let I={name:R};if(t.locationHint)I.locationHint=t.locationHint;let L=await this.request("POST","/buckets",I,m);return{bucket:{...L,name:L?.name||R},created:!0}}async getCors(R,t={}){try{return(await this.request("GET",`${this.bucketPath(R)}/cors`,void 0,t))?.rules??[]}catch(m){if(m instanceof co&&!(m instanceof Hi)&&(m.hasCode($f)||m.status===404))return[];throw m}}async putCors(R,t,m={}){if(t.length===0){await this.request("DELETE",`${this.bucketPath(R)}/cors`,void 0,m);return}await this.request("PUT",`${this.bucketPath(R)}/cors`,{rules:t},m)}async ensureCors(R,t,m={}){let k=await this.getCors(R,m);if(na(k,t))return!1;return await this.putCors(R,t,m),!0}async getLifecycle(R,t={}){return(await this.request("GET",`${this.bucketPath(R)}/lifecycle`,void 0,t))?.rules??[]}async putLifecycle(R,t,m={}){await this.request("PUT",`${this.bucketPath(R)}/lifecycle`,{rules:t},m)}async ensureLifecycle(R,t,m={}){let k=await this.getLifecycle(R,m);if(ra(k,t))return!1;return await this.putLifecycle(R,t,m),!0}async listCustomDomains(R,t={}){return(await this.request("GET",`${this.bucketPath(R)}/domains/custom`,void 0,t))?.domains??[]}async attachCustomDomain(R,t,m={}){return this.request("POST",`${this.bucketPath(R)}/domains/custom`,{domain:t.domain,zoneId:t.zoneId,enabled:t.enabled??!0,minTLS:t.minTLS??"1.2"},m)}async updateCustomDomain(R,t,m,k={}){return this.request("PUT",`${this.bucketPath(R)}/domains/custom/${encodeURIComponent(t)}`,m,k)}async ensureCustomDomain(R,t,m={},k){let I=t.minTLS??"1.2",z=(k??await this.listCustomDomains(R,m)).find((X)=>X.domain.toLowerCase()===t.domain.toLowerCase());if(!z){let X=await this.attachCustomDomain(R,{...t,minTLS:I,enabled:!0},m);return{action:"attached",domain:{...X,domain:X?.domain||t.domain}}}let Y=z.minTLS??"1.0";if(z.enabled&&Y===I)return{action:"unchanged",domain:z};let Z=await this.updateCustomDomain(R,z.domain,{enabled:!0,minTLS:I},m);return{action:"updated",domain:{...z,...Z}}}async getManagedDomain(R,t={}){return this.request("GET",`${this.bucketPath(R)}/domains/managed`,void 0,t)}async setManagedDomain(R,t,m={}){let k=await this.getManagedDomain(R,m);if(k?.enabled===t)return{changed:!1,domain:k};return{changed:!0,domain:await this.request("PUT",`${this.bucketPath(R)}/domains/managed`,{enabled:t},m)}}}function ws(R){if(Array.isArray(R))return`[${R.map(ws).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${ws(k)}`).join(",")}}`;return JSON.stringify(R)}function Jd(R,t){let m=(k)=>k&&k.length>0?[...k].map(String).sort():void 0;return{id:t?R.id:void 0,allowed:{origins:m(R.allowed?.origins),methods:m(R.allowed?.methods?.map((k)=>k.toUpperCase())),headers:m(R.allowed?.headers?.map((k)=>k.toLowerCase()))},exposeHeaders:m(R.exposeHeaders?.map((k)=>k.toLowerCase())),maxAgeSeconds:R.maxAgeSeconds}}function na(R,t){if(R.length!==t.length)return!1;return t.every((m,k)=>{let I=m.id!==void 0;return ws(Jd(R[k],I))===ws(Jd(m,I))})}function ra(R,t){if(R.length!==t.length)return!1;let m=(k)=>ws([...k].map((I)=>({...I,storageClassTransitions:I.storageClassTransitions?.length?I.storageClassTransitions:void 0})).sort((I,L)=>I.id.localeCompare(L.id)));return m(R)===m(t)}var kf="r2 cache",Af=/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;async function tl(R,t={}){let m=t.log??(()=>{}),k={buckets:[],warnings:[]},I=R.infrastructure?.r2??R.r2,L=Object.entries(I?.buckets??{});if(L.length===0)return m("R2: no buckets declared, skipping."),k;if(!t.apiToken||!t.accountId){let ne=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),ie=`R2: ${L.length} bucket(s) declared but ${ne} is not set, skipping.`;return m(ie),k.warnings.push(ie),k}let z=t.dryRun===!0,Y=new Oo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),Z=new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),X=new Map;for(let[ne,ie]of L){let se=ie?.name;if(!se||!Af.test(se)){k.warnings.push(`R2: bucket '${ne}' has an invalid name '${se??""}' (3-63 chars: lowercase letters, digits, hyphens), skipping.`);continue}m(`R2: ${z?"checking":"reconciling"} bucket ${se}...`);let be={name:se,changes:[],domains:[]};if(k.buckets.push(be),await Rf(ie,{r2:Y,cloudflare:Z,dryRun:z,summary:be,warnings:k.warnings,claimed:X,log:m}),be.changes.length===0)m(`R2: ${se} is in sync.`);else for(let Ae of be.changes)m(`R2: ${se}: ${Ae}`)}return k}async function Rf(R,t){let{r2:m,dryRun:k,summary:I,warnings:L}=t,z=R.name,Y={jurisdiction:R.jurisdiction},Z=(be,Ae)=>{let le=k?Ae&&`would ${Ae}`:be;if(le)I.changes.push(le)},X;if(k)X=await m.getBucket(z,Y)!==null;else{let{created:be}=await m.ensureBucket(z,{locationHint:R.locationHint,jurisdiction:R.jurisdiction});if(X=!0,be)Z("created","")}if(!X)Z("","create bucket");let ne=Pf(R.customDomains);await Ss(t,`cors on ${z}`,async()=>{if(!R.cors)return;if(!X){Z("cors updated","set cors");return}let be=await m.getCors(z,Y);if(na(be,R.cors))return;if(!k)await m.putCors(z,R.cors,Y);Z(R.cors.length===0?"cors removed":"cors updated",R.cors.length===0?"remove cors":"update cors")}),await Ss(t,`lifecycle on ${z}`,async()=>{if(!R.lifecycle)return;let be=R.lifecycle.map(Xd);if(X){let Ae=await m.getLifecycle(z,Y);if(ra(Ae,be))return}if(!k)await m.putLifecycle(z,be,Y);Z("lifecycle updated","update lifecycle")}),await Ss(t,`r2.dev URL on ${z}`,async()=>{let be=R.publicDevUrl===!0;if(!X){if(be)Z("r2.dev URL enabled","enable r2.dev URL");return}if((await m.getManagedDomain(z,Y))?.enabled===be)return;if(!k)await m.setManagedDomain(z,be,Y);Z(be?"r2.dev URL enabled":"r2.dev URL disabled",be?"enable r2.dev URL":"disable r2.dev URL")});let ie=[];if(ne.length>0&&X)try{ie=await m.listCustomDomains(z,Y)}catch(be){if(be instanceof Hi)throw be;L.push(`R2: could not list custom domains on ${z}: ${nl(be)}`)}let se=new Map;for(let{domain:be,minTLS:Ae}of ne){let le=t.claimed.get(be);if(le&&le!==z){L.push(`R2: ${be} is declared on both ${le} and ${z}; leaving it on ${le}.`);continue}t.claimed.set(be,z);let ke=ie.find((Se)=>Se.domain.toLowerCase()===be),De=Ae??"1.2";if(ke&&ke.enabled&&(ke.minTLS??"1.0")===De){if(I.domains.push({domain:be,status:el(ke)}),ke.zoneId)se.set(be,ke.zoneId);continue}await Ss(t,`custom domain ${be} on ${z}`,async()=>{if(ke){if(!k)await m.updateCustomDomain(z,ke.domain,{enabled:!0,minTLS:De},Y);if(Z(`custom domain ${be} updated`,`update custom domain ${be}`),I.domains.push({domain:be,status:el({...ke,enabled:!0})}),ke.zoneId)se.set(be,ke.zoneId);return}let Se=await t.cloudflare.zoneIdFor(be);if(se.set(be,Se),!k)await m.ensureCustomDomain(z,{domain:be,zoneId:Se,minTLS:De},Y,ie);Z(`custom domain ${be} attached`,`attach custom domain ${be}`),I.domains.push({domain:be,status:k?"not attached":"pending"})},()=>I.domains.push({domain:be,status:"error"}))}if(R.cache&&ne.length>0)await If(R,ne.map((be)=>be.domain).filter((be)=>t.claimed.get(be)===z),se,t,Z)}async function If(R,t,m,k,I){let L=Zd(R.cache);if(!L||t.length===0)return;let z=new Map;for(let Y of t){let Z=m.get(Y);if(!Z)try{Z=await k.cloudflare.zoneIdFor(Y)}catch(X){k.warnings.push(`R2: could not resolve the zone for ${Y}, cache rule skipped: ${nl(X)}`);continue}z.set(Z,[...z.get(Z)??[],Y])}for(let Y of z.values()){let Z={action:"set_cache_settings",description:`${kr} ${kf}`,expression:`(${Dr(Y)})`,enabled:!0,action_parameters:L};await Ss(k,`cache rule for ${Y.join(", ")}`,async()=>{let X=await k.cloudflare.getPhaseRules(Y[0],"http_request_cache_settings");if(Qd(X,Z))return;if(!k.dryRun){let ne=await k.cloudflare.putManagedPhaseRules(Y[0],"http_request_cache_settings",[Z]);if(!ne.success)throw Error(ne.message||"cache rule write failed")}I(`cache rule updated for ${Y.join(", ")}`,`update cache rule for ${Y.join(", ")}`)})}}function Zd(R){if(R.edgeTtl===void 0&&R.browserTtl===void 0)return null;let t={cache:!0};if(R.edgeTtl!==void 0)t.edge_ttl={mode:"override_origin",default:R.edgeTtl};if(R.browserTtl!==void 0)t.browser_ttl={mode:"override_origin",default:R.browserTtl};return t}function Qd(R,t){let m=Nr(t.expression),k=Mi(t.expression),I=(Y)=>(Y.description||"").startsWith(kr),L=(Y)=>Y.action===t.action&&Y.description===t.description&&(Y.enabled??!0)===(t.enabled??!0)&&Mi(Y.expression)===k&&ca(Y.action_parameters)===ca(t.action_parameters),z=!1;for(let Y of R){if(!I(Y))continue;let Z=Nr(Y.expression);if(!m.some((ne)=>Z.includes(ne)))continue;if(L(Y)&&m.every((ne)=>Z.includes(ne))&&!z){z=!0;continue}return!1}return z}function Xd(R){let t={id:R.id,enabled:R.enabled??!0,conditions:{prefix:R.prefix??""}};if(R.expireAfterDays!==void 0)t.deleteObjectsTransition={condition:{type:"Age",maxAge:Xc(R.expireAfterDays)}};else if(R.expireOn!==void 0)t.deleteObjectsTransition={condition:{type:"Date",date:R.expireOn}};if(R.abortMultipartUploadsAfterDays!==void 0)t.abortMultipartUploadsTransition={condition:{type:"Age",maxAge:Xc(R.abortMultipartUploadsAfterDays)}};if(R.infrequentAccessAfterDays!==void 0)t.storageClassTransitions=[{storageClass:"InfrequentAccess",condition:{type:"Age",maxAge:Xc(R.infrequentAccessAfterDays)}}];return t}function Xc(R){return Math.round(R*86400)}function Pf(R){let t=new Set,m=[];for(let k of R??[]){let I=typeof k==="string"?{domain:k}:k,L=I.domain?.trim().replace(/\.$/,"").toLowerCase();if(!L||t.has(L))continue;t.add(L),m.push({domain:L,minTLS:I.minTLS})}return m}function el(R){if(!R.enabled)return"disabled";let t=R.status?.ownership,m=R.status?.ssl;if(t==="active"&&m==="active")return"active";for(let k of[t,m])if(k==="error"||k==="blocked"||k==="deactivated")return k;return"pending"}async function Ss(R,t,m,k){try{await m()}catch(I){if(I instanceof Hi)throw I;R.warnings.push(`R2: ${t} failed: ${nl(I)}`),k?.()}}function nl(R){return R instanceof Error?R.message:String(R)}function ca(R){if(Array.isArray(R))return`[${R.map(ca).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${ca(k)}`).join(",")}}`;return JSON.stringify(R)}import{basename as Lf,extname as Ff}from"node:path";import{createHash as xf}from"node:crypto";var Df="https://api.cloudflare.com/client/v4",Gi="TS_CLOUD_CONTENT_HASH",Cs="2025-09-01",il="application/javascript+module",Ef=10007,Tf=[1e4,9109];class _o extends Error{status;errors;constructor(R,t,m=[]){super(R);this.name="WorkersApiError",this.status=t,this.errors=m}hasCode(R){return this.errors.some((t)=>t.code===R)}}class da extends _o{permission;constructor(R,t,m,k=[]){super(`The Cloudflare API token is missing the "${R}" permission (${t}). Edit the token in the Cloudflare dashboard (My Profile, API Tokens), add it, then re-run the deploy.`,m,k);this.name="WorkersPermissionError",this.permission=R}}class ua{name="cloudflare-workers";apiToken;accountId;fetchImpl;constructor(R){if(!R.apiToken)throw Error("Cloudflare Workers needs an API token");if(!R.accountId)throw Error("Cloudflare Workers needs an account id");this.apiToken=R.apiToken,this.accountId=R.accountId,this.fetchImpl=R.fetch??((t,m)=>fetch(t,m))}async request(R,t,m){let k={Authorization:`Bearer ${this.apiToken}`},I;if(m instanceof FormData)I=m;else if(m!==void 0)k["Content-Type"]="application/json",I=JSON.stringify(m);let L=await this.fetchImpl(`${Df}/accounts/${this.accountId}/workers${t}`,{method:R,headers:k,body:I}),z=await L.text(),Y;try{Y=JSON.parse(z)}catch{throw new _o(`Cloudflare Workers API returned ${L.status} with a non-JSON body: ${z.slice(0,200)}`,L.status)}if(!Y.success){let Z=Y.errors??[],X=Z.map((ne)=>`${ne.code}: ${ne.message}`).join(", ");if(Nf(L.status,Z))throw new da(Of(t),`${R} ${t} -> ${L.status}${X?`, ${X}`:""}`,L.status,Z);throw new _o(`Cloudflare Workers API error (${L.status}) on ${R} ${t}: ${X||z.slice(0,200)}`,L.status,Z)}return Y.result}scriptPath(R){return`/scripts/${encodeURIComponent(R)}`}async getSettings(R){try{return await this.request("GET",`${this.scriptPath(R)}/settings`)}catch(t){if(t instanceof da)throw t;if(t instanceof _o&&(t.hasCode(Ef)||t.status===404))return null;throw t}}async getScript(R){return this.getSettings(R)}async uploadModuleScript(R,t){return this.request("PUT",this.scriptPath(R),tu(t))}async ensureModuleScript(R,t){let m=ks(t),k=await this.getSettings(R);if(k&&ma(k,t,m))return{action:"unchanged",hash:m};return await this.uploadModuleScript(R,nu(t,m)),{action:k?"updated":"created",hash:m}}async listCustomDomains(R={}){let t=new URLSearchParams;if(R.service)t.set("service",R.service);if(R.hostname)t.set("hostname",R.hostname);if(R.zoneId)t.set("zone_id",R.zoneId);let m=t.toString(),k=m?`?${m}`:"";return await this.request("GET",`/domains${k}`)??[]}async attachCustomDomain(R,t){let m={hostname:R,service:t.service,environment:t.environment??"production"};if(t.zoneId)m.zone_id=t.zoneId;return this.request("PUT","/domains",m)}async detachCustomDomain(R){await this.request("DELETE",`/domains/${encodeURIComponent(R)}`)}async ensureCustomDomain(R,t,m){let I=(m??await this.listCustomDomains({hostname:R})).find((z)=>z.hostname.toLowerCase()===R.toLowerCase());if(I&&I.service===t.service)return{action:"unchanged",domain:I};if(I)throw Error(`${R} is attached to the Worker '${I.service}'. Detach it there first (Workers & Pages, ${I.service}, Settings, Domains & Routes); ts-cloud does not move it.`);let L=await this.attachCustomDomain(R,t);return{action:"attached",domain:{...L,hostname:L?.hostname||R}}}}function Nf(R,t){if(t.some((m)=>Tf.includes(m.code)))return!0;return(R===401||R===403)&&t.length===0}function Of(R){if(R.startsWith("/domains"))return"Workers Routes: Edit (zone, for Workers custom domains) and Workers Scripts: Edit (account)";return"Workers Scripts: Edit (account)"}function tu(R){if(!R.modules.some((k)=>k.name===R.mainModule))throw Error(`Worker main module '${R.mainModule}' is not one of the uploaded modules`);let t={main_module:R.mainModule,bindings:R.bindings??[],compatibility_date:R.compatibilityDate??Cs,compatibility_flags:R.compatibilityFlags??[],keep_bindings:["secret_text"]},m=new FormData;m.append("metadata",JSON.stringify(t));for(let k of R.modules)m.append(k.name,new Blob([k.content],{type:k.type}),k.name);return m}function ks(R){let t={mainModule:R.mainModule,modules:[...R.modules].sort((m,k)=>m.name.localeCompare(k.name)).map((m)=>({name:m.name,type:m.type,sha256:eu(m.content)})),bindings:[...R.bindings??[]].filter((m)=>m.name!==Gi).sort((m,k)=>m.name.localeCompare(k.name)),compatibilityDate:R.compatibilityDate??Cs,compatibilityFlags:[...R.compatibilityFlags??[]].sort()};return eu(rl(t))}function nu(R,t=ks(R)){return{...R,bindings:[...(R.bindings??[]).filter((m)=>m.name!==Gi),{type:"plain_text",name:Gi,text:t}]}}function ma(R,t,m){let k=R.bindings??[],I=k.find((L)=>L.name===Gi&&L.type==="plain_text");if(!I||I.text!==m)return!1;return(t.bindings??[]).every((L)=>{let z=k.find((Z)=>Z.name===L.name);if(!z||z.type!==L.type)return!1;let Y=L.type==="r2_bucket"?"bucket_name":L.type==="plain_text"?"text":void 0;return!Y||z[Y]===L[Y]})}function eu(R){return xf("sha256").update(R).digest("hex")}function rl(R){if(Array.isArray(R))return`[${R.map(rl).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${rl(k)}`).join(",")}}`;return JSON.stringify(R)}async function ol(R){if(!await Bun.file(R).exists())throw Error(`Worker entry not found: ${R}`);let t;try{t=await Bun.build({entrypoints:[R],target:"browser",format:"esm",minify:!0,external:["cloudflare:*"]})}catch(I){throw Error(`Bundling Worker ${R} failed: ${jf(I)}`)}if(!t.success)throw Error(`Bundling Worker ${R} failed: ${t.logs.map((I)=>String(I.message??I)).join("; ")}`);if(t.outputs.length!==1)throw Error(`Bundling Worker ${R} produced ${t.outputs.length} files (${t.outputs.map((I)=>I.path).join(", ")}); a Worker is uploaded as a single module, so remove the dynamic imports or asset imports that split it.`);let m=t.outputs[0];if(m.kind!=="entry-point")throw Error(`Bundling Worker ${R} produced a ${m.kind} instead of an entry module`);let k=await m.text();return{name:`${Lf(R,Ff(R))}.js`,content:k,type:il,size:new TextEncoder().encode(k).byteLength}}function jf(R){if(R instanceof AggregateError&&R.errors.length>0)return R.errors.map((t)=>t instanceof Error?t.message:String(t?.message??t)).join("; ");return R instanceof Error?R.message:String(R)}import{isAbsolute as Bf,resolve as _f}from"node:path";var Mf="https://api.cloudflare.com/client/v4",zf=/^[a-z0-9][a-z0-9_-]{0,62}$/;async function sl(R,t={}){let m=t.log??(()=>{}),k={workers:[],warnings:[]},I=Object.entries(R.infrastructure?.workers??R.workers??{});if(I.length===0)return m("Workers: none declared, skipping."),k;if(!t.apiToken||!t.accountId){let Y=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),Z=`Workers: ${I.length} Worker(s) declared but ${Y} is not set, skipping.`;return m(Z),k.warnings.push(Z),k}let L=R.infrastructure?.r2??R.r2,z={workers:new ua({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),r2:new Oo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),cloudflare:new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),apiToken:t.apiToken,fetch:t.fetch??((Y,Z)=>fetch(Y,Z)),projectRoot:t.projectRoot??process.cwd(),dryRun:t.dryRun===!0,warnings:k.warnings,log:m,r2ConfigDomains:Gf(L),r2Buckets:L,claimed:new Map};for(let[Y,Z]of I){let X=Z?.name;if(!X||!zf.test(X)){k.warnings.push(`Workers: '${Y}' has an invalid name '${X??""}' (1-63 chars: lowercase letters, digits, '-' and '_'), skipping.`);continue}if(!Z.entry){k.warnings.push(`Workers: ${X} has no entry, skipping.`);continue}m(`Workers: ${z.dryRun?"checking":"reconciling"} ${X}...`);let ne={name:X,changes:[],domains:[]};k.workers.push(ne),await Uf(Z,ne,z);for(let ie of ne.changes)m(`Workers: ${X}: ${ie}`)}return k}async function Uf(R,t,m){let k=R.name,I=Bf(R.entry)?R.entry:_f(m.projectRoot,R.entry),L;try{L=await ol(I)}catch(Y){throw Error(`Worker ${k}: ${zo(Y)}`)}t.changes.push(`bundled ${Jf(L.size)}`);let z={mainModule:L.name,modules:[{name:L.name,content:L.content,type:L.type}],bindings:ru(R,m),compatibilityDate:R.compatibilityDate??Cs,compatibilityFlags:R.compatibilityFlags??[]};if(m.dryRun){let Y=await m.workers.getSettings(k);t.changes.push(Y&&ma(Y,z,ks(z))?"unchanged":"would upload")}else{let{action:Y}=await m.workers.ensureModuleScript(k,z);t.changes.push(Y==="unchanged"?"unchanged":"uploaded")}for(let Y of Kf(R.customDomains))await Wf(k,Y,t,m)}async function Wf(R,t,m,k){let I=(be)=>{m.domains.push({domain:t,status:be})},L=(be)=>{k.warnings.push(`Workers: ${be}`),I("conflict")},z=k.claimed.get(t);if(z&&z!==R){L(`${t} is declared on both ${z} and ${R}; leaving it on ${z}.`);return}k.claimed.set(t,R);let Y=k.r2ConfigDomains.get(t);if(Y){L(`${t} is also declared as a custom domain of the R2 bucket '${Y}' (r2.buckets). A hostname serves either a bucket or a Worker. Remove it from the bucket's customDomains and detach it in the dashboard (R2, ${Y}, Settings, Custom Domains) first; to serve the bucket through the Worker, bind it with bindings.r2Buckets instead.`);return}let Z=await Vf(k);if(Z===null){I("error");return}let X=Z.find((be)=>be.hostname.toLowerCase()===t);if(X?.service===R){I("active");return}if(X){L(`${t} is attached to the Worker '${X.service}'. Detach it there first (Workers & Pages, ${X.service}, Settings, Domains & Routes); it is not moved automatically.`);return}let ne=(await qf(k))?.get(t);if(ne){L(`${t} is attached to the R2 bucket '${ne}' as a custom domain. Detach it first (R2, ${ne}, Settings, Custom Domains, then re-run the deploy); it is not detached automatically. To serve the bucket through the Worker, bind it with bindings.r2Buckets.`);return}let ie;try{ie=await k.cloudflare.zoneIdFor(t)}catch(be){k.warnings.push(`Workers: could not resolve the zone for ${t}, not attached: ${zo(be)}`),I("error");return}let se=await Hf(k,ie,t);if(se.length>0){let be=se.map((Ae)=>`${Ae.type} ${Ae.content}`).join(", ");L(`${t} already has a DNS record (${be}). A Worker custom domain creates its own record, so Cloudflare will not attach over it. Delete the record first (DNS, Records), then re-run the deploy; it is not deleted automatically.`);return}if(k.dryRun){m.changes.push(`would attach custom domain ${t}`),I("not attached");return}try{await k.workers.ensureCustomDomain(t,{service:R,zoneId:ie},Z),m.changes.push(`custom domain ${t} attached`),Z.push({id:"",hostname:t,service:R,zone_id:ie}),I("pending")}catch(be){k.warnings.push(`Workers: custom domain ${t} on ${R} failed: ${zo(be)}`),I("error")}}async function Vf(R){if(R.attached!==void 0)return R.attached;try{R.attached=await R.workers.listCustomDomains()}catch(t){R.warnings.push(`Workers: could not list Worker custom domains, none attached: ${zo(t)}`),R.attached=null}return R.attached}async function qf(R){if(R.r2AccountDomains!==void 0)return R.r2AccountDomains;let t=new Map;try{let m=(await R.r2.listBuckets()).map((k)=>({name:k.name}));for(let k of Object.values(R.r2Buckets?.buckets??{}))if(k.jurisdiction&&k.jurisdiction!=="default")m.push({name:k.name,jurisdiction:k.jurisdiction});for(let k of m){let I=await R.r2.listCustomDomains(k.name,{jurisdiction:k.jurisdiction}).catch(()=>[]);for(let L of I)t.set(L.domain.toLowerCase(),k.name)}R.r2AccountDomains=t}catch(m){R.log(`Workers: could not check R2 custom domains (${zo(m)}); relying on the DNS check.`),R.r2AccountDomains=null}return R.r2AccountDomains}async function Hf(R,t,m){try{let k=await R.fetch(`${Mf}/zones/${t}/dns_records?name=${encodeURIComponent(m)}&per_page=100`,{method:"GET",headers:{Authorization:`Bearer ${R.apiToken}`}}),I=await k.json();if(!I?.success)throw Error(`HTTP ${k.status}`);return(I.result??[]).filter((L)=>L.name?.toLowerCase()===m).map((L)=>({type:L.type??"?",content:L.content??""}))}catch(k){return R.log(`Workers: could not read DNS records for ${m} (${zo(k)}); attaching anyway.`),[]}}function ru(R,t){let m=[],k=new Set,I=(z)=>{if(z===Gi)return t.warnings.push(`Workers: ${R.name}: binding name ${Gi} is reserved for ts-cloud, ignored.`),!1;if(k.has(z))return t.warnings.push(`Workers: ${R.name}: binding ${z} is declared twice; the first one wins.`),!1;return k.add(z),!0},L=new Map;for(let z of Object.values(t.r2Buckets?.buckets??{}))if(z.jurisdiction&&z.jurisdiction!=="default")L.set(z.name,z.jurisdiction);for(let[z,Y]of Object.entries(R.bindings?.r2Buckets??{})){if(!I(z))continue;let Z=L.get(Y);m.push(Z?{type:"r2_bucket",name:z,bucket_name:Y,jurisdiction:Z}:{type:"r2_bucket",name:z,bucket_name:Y})}for(let[z,Y]of Object.entries(R.bindings?.vars??{}))if(I(z))m.push({type:"plain_text",name:z,text:String(Y)});return m}function Gf(R){let t=new Map;for(let m of Object.values(R?.buckets??{}))for(let k of m?.customDomains??[]){let I=iu(typeof k==="string"?k:k.domain);if(I)t.set(I,m.name)}return t}function Kf(R){return[...new Set((R??[]).map(iu).filter(Boolean))]}function iu(R){return(R??"").trim().replace(/\.$/,"").toLowerCase()}function Jf(R){if(R<1024)return`${R} B`;if(R<1048576)return`${(R/1024).toFixed(1)} KB`;return`${(R/1024/1024).toFixed(1)} MB`}function zo(R){return R instanceof Error?R.message:String(R)}async function eg(R){let t=la();if(t.emptyEnvKey||t.emptyEnvSecret)a("Empty AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY env var detected — likely a misconfigured .env file. Remove the empty lines or fill them in.");e(`AWS credentials: ${t.description}`);try{let k=await new bt(R).getCallerIdentity();if(k.Arn)e(`AWS identity: ${k.Arn}`)}catch(m){a(`Could not verify AWS identity: ${m.message}`)}}function tg(){try{return dl("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function al(R,t,m,k){let{ensureManagementDashboard:I}=await import("./chunk-wm0rq725.js");I(R,{logger:{info:e,warn:a}});let L=R.sites||{},z=Object.entries(L);if(z.length===0)return a("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(k&&!L[k])return r(`Site '${k}' was not found. Configured sites: ${z.map(([De])=>De).join(", ")}`),!1;let Y=z.filter(([De,Se])=>{if(!Se)return!1;if(k&&De!==k)return!1;if(A(Se)==="bucket")return a(`Site '${De}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return js(Se)});if(k)e(`Deploying only '${k}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let Z=R.project.slug,ne=(R.infrastructure?.compute||{}).runtime||"bun",ie=O({config:R}),se=tg(),be=new Map,Ae=new Map,le={step:(De)=>u(De),error:(De)=>r(De)};if(!await vs(R,"beforeDeploy",le))return!1;if(!await vs(R,"beforeBuild",le))return!1;for(let[De,Se]of Y){let Re=A(Se);if(i(`Preparing site: ${De}`),e(`Domain: ${Se.domain||"(none)"}`),e(`Source: ${Se.root}`),e(`Kind: ${Re==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),Re==="server-app")e(`Start: ${Se.start}`),e(`Port: ${Se.port??"(unset)"}`);if(Se.build){u(`Running build: ${Se.build}`);try{dl(Se.build,{stdio:"inherit",cwd:process.cwd()})}catch(Ve){return r(`Build failed for site '${De}': ${Ve.message}`),!1}}let Pe=Gd({root:Se.root,siteName:De,expectIndex:Re==="server-static"});for(let Ve of Pe)if(Ve.level==="error")r(Ve.message);else a(Ve.message);if(Pe.some((Ve)=>Ve.level==="error"))return!1;let ze=Se.build?void 0:JSON.stringify([Xf(Se.root),[...Se.exclude||[]].sort()]),Le=ze?Ae.get(ze):void 0;if(Le){u(`Reusing package for ${Se.root} → ${Le}`),be.set(De,Le);continue}let Be=lu(cu(),`${Z}-${De}-${se}.tar.gz`);u(`Packaging ${Se.root} → ${Be}`);try{let Ve=(Se.exclude||[]).map((ct)=>`--exclude=${ct}`);Yf("tar",["czf",Be,"-C",Se.root,...Ve,"."],{stdio:"inherit",env:{...process.env,COPYFILE_DISABLE:"1"}})}catch(Ve){return r(`Failed to package '${De}': ${Ve.message}`),!1}if(be.set(De,Be),ze)Ae.set(ze,Be)}if(!await vs(R,"afterBuild",le))return!1;let ke=await Eo({config:k?{...R,sites:Object.fromEntries(Y)}:R,rpxConfig:k?R:void 0,environment:t,driver:ie,sha:se,runtime:ne,tarballForSite:(De)=>{let Se=be.get(De);if(!Se)throw Error(`Missing tarball for site '${De}'`);return Se},logger:{info:(De)=>e(De),warn:(De)=>a(De),error:(De)=>r(De),step:(De)=>u(De),success:(De)=>n(De)}});if(ke&&!await vs(R,"afterDeploy",le))return!1;return ke}async function pa(R){let t=new Yr;if(u("Running pre-deployment security scan..."),R.exclude?.length)e(`Excluding from the scan: ${R.exclude.join(", ")}`);let m=await t.scan({directory:R.sourceDir,failOnSeverity:R.failOnSeverity||"critical",skipPatterns:R.skipPatterns,exclude:R.exclude});return{passed:m.passed,result:m}}function ng(){let R=lu(cu(),`ts-cloud-empty-scan-${process.pid}`);return au(R,{recursive:!0}),R}function fa(R){let{summary:t,findings:m,scannedFiles:k,duration:I}=R;if(e(`
375
+ Invalidation is in progress. Use --wait to wait for completion.`)}catch(m){r(`Invalidation failed: ${m.message}`)}})}function qc(R){for(let[t,m]of[["team:add <email> <role>","Invite an organization member"],["team:list","List organization members"],["team:remove <email>","Revoke organization membership"]])R.command(t,m).action(async(...k)=>En(t.split(" ")[0],{target:String(k[0]??""),message:"Legacy IAM-backed team commands are deprecated and cannot safely represent organization-scoped access.",nextAction:"Use the Team dashboard or organization invitation API; this command exits without changing IAM."}))}import{execFileSync as Yf,execSync as dl}from"node:child_process";import{copyFileSync as As,existsSync as In,mkdirSync as au,readFileSync as ll,writeFileSync as Zf}from"node:fs";import{tmpdir as cu}from"node:os";import{dirname as Qf,join as lu,resolve as Xf}from"node:path";import{existsSync as Hc,readdirSync as Vd,statSync as Gc}from"node:fs";import{join as ea}from"node:path";var pf=new Set([".DS_Store","Thumbs.db",".gitkeep",".keep"]);function qd(R){return pf.has(R)}function Hd(R,t=0){if(t>8)return!0;let m;try{m=Vd(R)}catch{return!1}for(let k of m){if(qd(k))continue;let I=ea(R,k),L;try{L=Gc(I)}catch{continue}if(L.isFile())return!0;if(L.isDirectory()&&Hd(I,t+1))return!0}return!1}function ff(R){let t;try{t=Vd(R)}catch{return[]}let m=[];for(let k of t){if(qd(k))continue;let I=ea(R,k);try{if(Gc(I).isDirectory()&&Hc(ea(I,"index.html")))m.push(k)}catch{}}return m.sort((k,I)=>k.localeCompare(I))}function Gd(R){let{root:t,siteName:m,expectIndex:k}=R,I=[];if(!Hc(t))return I.push({level:"error",message:`Build output not found at ${t} for site '${m}'`}),I;if(!Gc(t).isDirectory())return I.push({level:"error",message:`Site '${m}' has root ${t}, which is a file, not a directory`}),I;if(!Hd(t))return I.push({level:"error",message:`Site '${m}' would ship an empty release: ${t} contains no files. Check that the build ran and wrote where 'root' points.`}),I;if(!k)return I;if(Hc(ea(t,"index.html")))return I;let L=ff(t);if(L.length===1){let z=`${t.replace(/\/+$/,"")}/${L[0]}`;return I.push({level:"error",message:`Site '${m}' has no index.html at the top of ${t}, but ${z} has one. The generator wrote one level down, so this release would serve 404s at the domain root. Set root: '${z}'.`}),I}if(L.length>1)return I.push({level:"warning",message:`Site '${m}' has no index.html at the top of ${t}. These subdirectories have one: ${L.join(", ")}. The domain root will 404.`}),I;return I.push({level:"warning",message:`Site '${m}' has no index.html anywhere under ${t}. The domain root will 404.`}),I}function gf(R){if(!R)return[];if(Array.isArray(R))return R.map(String);let t=R,m=t.Items??t.Item;if(!m)return[];if(Array.isArray(m))return m.map(String);if(typeof m==="object"&&m!==null){let k=m;if("Item"in k){let I=k.Item;if(!I)return[];return Array.isArray(I)?I.map(String):[String(I)]}if("CNAME"in k){let I=k.CNAME;if(!I)return[];return Array.isArray(I)?I.map(String):[String(I)]}return Object.values(k).flatMap((I)=>{if(Array.isArray(I))return I.map(String);return typeof I==="string"?[I]:[]})}return[String(m)]}async function ta(R){if(R.length===0)return;let t=new E,m=await t.listDistributions(),k=[...new Set(R.map((I)=>I.toLowerCase()))];for(let I of k){let L=m.find((Y)=>gf(Y.Aliases).some((X)=>X.toLowerCase()===I));if(!L?.Id){a(`No CloudFront distribution found for ${I} — skipping dynamic HTTP method sync`);continue}if(await t.ensureDynamicHttpMethods(L.Id))n(`CloudFront ${L.Id} (${I}): enabled POST/PUT/PATCH/DELETE on dynamic paths`);else e(`CloudFront ${L.Id} (${I}): already allows dynamic HTTP methods`)}}import{execSync as hf}from"node:child_process";async function yf(R,t,m,k={},I=process.cwd()){if(!R)return;if(k.step?.(`Running ${m} hook`),typeof R==="string"){hf(R,{stdio:"inherit",cwd:I});return}await R(t)}async function vs(R,t,m={},k){try{return await yf(R.hooks?.[t],R,t,m,k),!0}catch(I){return m.error?.(`${t} hook failed: ${I?.message||I}`),!1}}var Si=(R)=>R===void 0?void 0:R?"on":"off";function Jc(R){let t={ssl:R.ssl,always_use_https:Si(R.alwaysUseHttps),automatic_https_rewrites:Si(R.automaticHttpsRewrites),min_tls_version:R.minTlsVersion,tls_1_3:Si(R.tls13),brotli:Si(R.brotli),http3:Si(R.http3),"0rtt":Si(R.zeroRtt),early_hints:Si(R.earlyHints),browser_cache_ttl:R.browserCacheTtl,always_online:Si(R.alwaysOnline),websockets:Si(R.websockets),email_obfuscation:Si(R.emailObfuscation)};if(R.hsts)t.security_header={strict_transport_security:{enabled:R.hsts.enabled,max_age:R.hsts.maxAge??31536000,include_subdomains:R.hsts.includeSubdomains??!1,preload:R.hsts.preload??!1,nosniff:R.hsts.noSniff??!0}};for(let m of Object.keys(t))if(t[m]===void 0)delete t[m];return{...t,...R.raw??{}}}var bs={ssl:"strict",alwaysUseHttps:!0,automaticHttpsRewrites:!0,minTlsVersion:"1.2",tls13:!0,brotli:!0,http3:!0,earlyHints:!0,alwaysOnline:!0,emailObfuscation:!1,browserCacheTtl:0};import{connect as vf}from"node:tls";async function Yc(R){let{address:t,serverName:m,port:k=443,timeoutMs:I=5000}=R;return new Promise((L)=>{let z=!1,Y=(X)=>{if(z)return;z=!0;try{Z.destroy()}catch{}L(X)},Z=vf({host:t,port:k,servername:m,rejectUnauthorized:!1,timeout:I});Z.once("secureConnect",()=>{if(Z.authorized){Y({reachable:!0,trusted:!0});return}Y({reachable:!0,trusted:!1,reason:Z.authorizationError?String(Z.authorizationError):"origin certificate is not trusted for this hostname"})}),Z.once("timeout",()=>{Y({reachable:!1,trusted:!1,reason:`no TLS handshake within ${I}ms`})}),Z.once("error",(X)=>{Y({reachable:!1,trusted:!1,reason:X.message})})})}function bf(R,t){let m=t.replace(/\.$/,"").toLowerCase();return R.some((k)=>{let I=k.replace(/\.$/,"").toLowerCase();if(I===m)return!0;if(!I.startsWith("*."))return!1;let L=I.slice(2);if(!m.endsWith(`.${L}`))return!1;return!m.slice(0,m.length-L.length-1).includes(".")})}async function Zc(R){let{provider:t,zone:m,hosts:k,ipv4:I,ipv6:L,proxied:z=!0,settings:Y=bs,cache:Z,originGuard:X,purge:ne=!0,ttl:ie=300,skipOriginProbe:se=!1,skipEdgeCertificateCheck:be=!1}=R,Ae={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(k.length===0)return Ae;let le=[],ke=z&&!be?await t.listEdgeCertificateHosts(m):null;for(let Se of k){let Re=z;if(Re&&ke&&!bf(ke,Se)){Re=!1;let ze=ke.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${ke.join(", ")})`;Ae.deferredProxy.push({host:Se,reason:ze}),Ae.warnings.push(`${Se}: publishing DNS-only — ${ze}. Proxying it would make Cloudflare terminate TLS with no certificate for the name, which fails the handshake outright rather than degrading. Universal SSL covers the apex and ONE level of subdomain, so a deeper name needs its own certificate; otherwise re-run the deploy once the certificate is active.`)}if(Re&&!se){let ze=await Yc({address:I,serverName:Se});if(!ze.trusted){Re=!1;let Le=ze.reason||"origin is not serving a trusted certificate";Ae.deferredProxy.push({host:Se,reason:Le}),Ae.warnings.push(`${Se}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${Le}). The origin issues certificates over HTTP-01, which needs the name to reach it directly; re-run the deploy once it has one and the record will be proxied.`)}}if(Re)le.push(Se);let Pe=[{type:"A",content:I}];if(L&&mo(Se))Pe.push({type:"AAAA",content:L});for(let{type:ze,content:Le}of Pe){let Be=await t.upsertRecord(m,{name:Se,type:ze,content:Le,ttl:ie,proxied:Re});if(Be.success)Ae.records.push({host:Se,type:ze,content:Le,proxied:Re});else Ae.warnings.push(`${Se} ${ze} → ${Le} failed: ${Be.message||"unknown provider error"}`)}}if(le.length===0){if(z)Ae.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return Ae}try{let Se=Jc(Y),Re=await t.applyZoneSettings(m,Se);Ae.settingsChanged=Re.changed;for(let Pe of Re.failed)Ae.warnings.push(`zone setting '${Pe.id}' could not be applied: ${Pe.error}`)}catch(Se){Ae.warnings.push(`zone settings could not be read: ${Se instanceof Error?Se.message:String(Se)}`)}let De=Qs(le,Z);if(De.length>0){let Se=await t.putManagedPhaseRules(m,"http_request_cache_settings",De);if(Se.success)Ae.cacheRules=De.length;else Ae.warnings.push(`cache rules could not be written: ${Se.message}`)}if(X){let Se=Ys(le,X.header,X.value);if(Se.length>0){let Re=await t.putManagedPhaseRules(m,"http_request_late_transform",Se);if(Re.success)Ae.originGuard=!0;else Ae.warnings.push(`origin guard header could not be written: ${Re.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(ne){if(Ae.purged=await t.purgeCache(m,{hosts:le}),!Ae.purged)Ae.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return Ae}var wf=(R)=>process.env[R];function Kd(R,t){let m=R.replace(/\.$/,"").toLowerCase();if(t){let k=t.replace(/\.$/,"").toLowerCase();if(m===k||m.endsWith(`.${k}`))return k}return m.split(".").slice(-2).join(".")}function Qc(R,t={}){let m=t.env??wf,k=R.infrastructure?.compute?.proxy?.cdn,I=[];if(!k||k.provider!=="cloudflare")return{plan:null,errors:I};if(k.originDomain)I.push(`compute.proxy.cdn.originDomain (${k.originDomain}) is ignored for Cloudflare: the proxy forwards to the address in the record it fronts, `+"so no separate origin hostname is needed — and publishing one gives clients a documented way around the edge.");let L=m("CLOUDFLARE_API_TOKEN");if(!L)return I.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:I};let z=R.sites??{},Y=k.frontedHosts?.length?[...new Set(k.frontedHosts.map((se)=>se.toLowerCase()))]:ho(z,{autoWww:R.infrastructure?.compute?.proxy?.autoWww!==!1});if(Y.length===0)return I.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:I};let Z=R.infrastructure?.dns?.domain,X=new Set(Y.map((se)=>Kd(se,Z)));if(X.size>1)return I.push(`Fronted hosts span more than one zone (${[...X].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:I};let ne=k.cloudflare??{},ie=k.secret?{header:k.secretHeader??"X-Origin-Verify",value:k.secret}:void 0;return{plan:{zone:[...X][0],hosts:Y,apiToken:L,zoneId:ne.zoneId??m("CLOUDFLARE_ZONE_ID"),accountId:ne.accountId??m("CLOUDFLARE_ACCOUNT_ID"),proxied:ne.proxied!==!1,settings:ne.settings??bs,cache:ne.cache,originGuard:ie,purge:ne.purgeOnDeploy!==!1,skipOriginProbe:ne.skipOriginProbe===!0},errors:I}}var Sf="https://api.cloudflare.com/client/v4",Yd=10042,Cf=10006,$f=10059;class co extends Error{status;errors;constructor(R,t,m=[]){super(R);this.name="R2ApiError",this.status=t,this.errors=m}hasCode(R){return this.errors.some((t)=>t.code===R)}}class Hi extends co{accountId;constructor(R,t,m=[]){super(`R2 is not enabled on Cloudflare account ${R}. Enable it once in the Cloudflare dashboard (R2 Object Storage, then follow the prompt to activate it), then re-run the deploy.`,t,m);this.name="R2NotEnabledError",this.accountId=R}}class Oo{name="cloudflare-r2";apiToken;accountId;fetchImpl;constructor(R){if(!R.apiToken)throw Error("Cloudflare R2 needs an API token");if(!R.accountId)throw Error("Cloudflare R2 needs an account id");this.apiToken=R.apiToken,this.accountId=R.accountId,this.fetchImpl=R.fetch??((t,m)=>fetch(t,m))}async requestEnvelope(R,t,m,k={}){let I={Authorization:`Bearer ${this.apiToken}`};if(m!==void 0)I["Content-Type"]="application/json";if(k.jurisdiction&&k.jurisdiction!=="default")I["cf-r2-jurisdiction"]=k.jurisdiction;let L=await this.fetchImpl(`${Sf}/accounts/${this.accountId}/r2${t}`,{method:R,headers:I,body:m===void 0?void 0:JSON.stringify(m)}),z=await L.text(),Y;try{Y=JSON.parse(z)}catch{throw new co(`Cloudflare R2 API returned ${L.status} with a non-JSON body: ${z.slice(0,200)}`,L.status)}if(!Y.success){let Z=Y.errors??[];if(Z.some((ne)=>ne.code===Yd))throw new Hi(this.accountId,L.status,Z);let X=Z.map((ne)=>`${ne.code}: ${ne.message}`).join(", ");throw new co(`Cloudflare R2 API error (${L.status}) on ${R} ${t}: ${X||z.slice(0,200)}`,L.status,Z)}return Y}async request(R,t,m,k){return(await this.requestEnvelope(R,t,m,k)).result}bucketPath(R){return`/buckets/${encodeURIComponent(R)}`}async listBuckets(R={}){let t=[],m;do{let k=new URLSearchParams({per_page:"1000"});if(m)k.set("cursor",m);let I=await this.requestEnvelope("GET",`/buckets?${k}`,void 0,R),L=I.result?.buckets??[];t.push(...L),m=L.length>0?I.result_info?.cursor||void 0:void 0}while(m);return t}async getBucket(R,t={}){try{return await this.request("GET",this.bucketPath(R),void 0,t)}catch(m){if(m instanceof Hi)throw m;if(m instanceof co&&(m.hasCode(Cf)||m.status===404))return null;throw m}}async ensureBucket(R,t={}){let m={jurisdiction:t.jurisdiction},k=await this.getBucket(R,m);if(k)return{bucket:k,created:!1};let I={name:R};if(t.locationHint)I.locationHint=t.locationHint;let L=await this.request("POST","/buckets",I,m);return{bucket:{...L,name:L?.name||R},created:!0}}async getCors(R,t={}){try{return(await this.request("GET",`${this.bucketPath(R)}/cors`,void 0,t))?.rules??[]}catch(m){if(m instanceof co&&!(m instanceof Hi)&&(m.hasCode($f)||m.status===404))return[];throw m}}async putCors(R,t,m={}){if(t.length===0){await this.request("DELETE",`${this.bucketPath(R)}/cors`,void 0,m);return}await this.request("PUT",`${this.bucketPath(R)}/cors`,{rules:t},m)}async ensureCors(R,t,m={}){let k=await this.getCors(R,m);if(na(k,t))return!1;return await this.putCors(R,t,m),!0}async getLifecycle(R,t={}){return(await this.request("GET",`${this.bucketPath(R)}/lifecycle`,void 0,t))?.rules??[]}async putLifecycle(R,t,m={}){await this.request("PUT",`${this.bucketPath(R)}/lifecycle`,{rules:t},m)}async ensureLifecycle(R,t,m={}){let k=await this.getLifecycle(R,m);if(ra(k,t))return!1;return await this.putLifecycle(R,t,m),!0}async listCustomDomains(R,t={}){return(await this.request("GET",`${this.bucketPath(R)}/domains/custom`,void 0,t))?.domains??[]}async attachCustomDomain(R,t,m={}){return this.request("POST",`${this.bucketPath(R)}/domains/custom`,{domain:t.domain,zoneId:t.zoneId,enabled:t.enabled??!0,minTLS:t.minTLS??"1.2"},m)}async updateCustomDomain(R,t,m,k={}){return this.request("PUT",`${this.bucketPath(R)}/domains/custom/${encodeURIComponent(t)}`,m,k)}async ensureCustomDomain(R,t,m={},k){let I=t.minTLS??"1.2",z=(k??await this.listCustomDomains(R,m)).find((X)=>X.domain.toLowerCase()===t.domain.toLowerCase());if(!z){let X=await this.attachCustomDomain(R,{...t,minTLS:I,enabled:!0},m);return{action:"attached",domain:{...X,domain:X?.domain||t.domain}}}let Y=z.minTLS??"1.0";if(z.enabled&&Y===I)return{action:"unchanged",domain:z};let Z=await this.updateCustomDomain(R,z.domain,{enabled:!0,minTLS:I},m);return{action:"updated",domain:{...z,...Z}}}async getManagedDomain(R,t={}){return this.request("GET",`${this.bucketPath(R)}/domains/managed`,void 0,t)}async setManagedDomain(R,t,m={}){let k=await this.getManagedDomain(R,m);if(k?.enabled===t)return{changed:!1,domain:k};return{changed:!0,domain:await this.request("PUT",`${this.bucketPath(R)}/domains/managed`,{enabled:t},m)}}}function ws(R){if(Array.isArray(R))return`[${R.map(ws).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${ws(k)}`).join(",")}}`;return JSON.stringify(R)}function Jd(R,t){let m=(k)=>k&&k.length>0?[...k].map(String).sort():void 0;return{id:t?R.id:void 0,allowed:{origins:m(R.allowed?.origins),methods:m(R.allowed?.methods?.map((k)=>k.toUpperCase())),headers:m(R.allowed?.headers?.map((k)=>k.toLowerCase()))},exposeHeaders:m(R.exposeHeaders?.map((k)=>k.toLowerCase())),maxAgeSeconds:R.maxAgeSeconds}}function na(R,t){if(R.length!==t.length)return!1;return t.every((m,k)=>{let I=m.id!==void 0;return ws(Jd(R[k],I))===ws(Jd(m,I))})}function ra(R,t){if(R.length!==t.length)return!1;let m=(k)=>ws([...k].map((I)=>({...I,storageClassTransitions:I.storageClassTransitions?.length?I.storageClassTransitions:void 0})).sort((I,L)=>I.id.localeCompare(L.id)));return m(R)===m(t)}var kf="r2 cache",Af=/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;async function tl(R,t={}){let m=t.log??(()=>{}),k={buckets:[],warnings:[]},I=R.infrastructure?.r2??R.r2,L=Object.entries(I?.buckets??{});if(L.length===0)return m("R2: no buckets declared, skipping."),k;if(!t.apiToken||!t.accountId){let ne=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),ie=`R2: ${L.length} bucket(s) declared but ${ne} is not set, skipping.`;return m(ie),k.warnings.push(ie),k}let z=t.dryRun===!0,Y=new Oo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),Z=new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),X=new Map;for(let[ne,ie]of L){let se=ie?.name;if(!se||!Af.test(se)){k.warnings.push(`R2: bucket '${ne}' has an invalid name '${se??""}' (3-63 chars: lowercase letters, digits, hyphens), skipping.`);continue}m(`R2: ${z?"checking":"reconciling"} bucket ${se}...`);let be={name:se,changes:[],domains:[]};if(k.buckets.push(be),await Rf(ie,{r2:Y,cloudflare:Z,dryRun:z,summary:be,warnings:k.warnings,claimed:X,log:m}),be.changes.length===0)m(`R2: ${se} is in sync.`);else for(let Ae of be.changes)m(`R2: ${se}: ${Ae}`)}return k}async function Rf(R,t){let{r2:m,dryRun:k,summary:I,warnings:L}=t,z=R.name,Y={jurisdiction:R.jurisdiction},Z=(be,Ae)=>{let le=k?Ae&&`would ${Ae}`:be;if(le)I.changes.push(le)},X;if(k)X=await m.getBucket(z,Y)!==null;else{let{created:be}=await m.ensureBucket(z,{locationHint:R.locationHint,jurisdiction:R.jurisdiction});if(X=!0,be)Z("created","")}if(!X)Z("","create bucket");let ne=Pf(R.customDomains);await Ss(t,`cors on ${z}`,async()=>{if(!R.cors)return;if(!X){Z("cors updated","set cors");return}let be=await m.getCors(z,Y);if(na(be,R.cors))return;if(!k)await m.putCors(z,R.cors,Y);Z(R.cors.length===0?"cors removed":"cors updated",R.cors.length===0?"remove cors":"update cors")}),await Ss(t,`lifecycle on ${z}`,async()=>{if(!R.lifecycle)return;let be=R.lifecycle.map(Xd);if(X){let Ae=await m.getLifecycle(z,Y);if(ra(Ae,be))return}if(!k)await m.putLifecycle(z,be,Y);Z("lifecycle updated","update lifecycle")}),await Ss(t,`r2.dev URL on ${z}`,async()=>{let be=R.publicDevUrl===!0;if(!X){if(be)Z("r2.dev URL enabled","enable r2.dev URL");return}if((await m.getManagedDomain(z,Y))?.enabled===be)return;if(!k)await m.setManagedDomain(z,be,Y);Z(be?"r2.dev URL enabled":"r2.dev URL disabled",be?"enable r2.dev URL":"disable r2.dev URL")});let ie=[];if(ne.length>0&&X)try{ie=await m.listCustomDomains(z,Y)}catch(be){if(be instanceof Hi)throw be;L.push(`R2: could not list custom domains on ${z}: ${nl(be)}`)}let se=new Map;for(let{domain:be,minTLS:Ae}of ne){let le=t.claimed.get(be);if(le&&le!==z){L.push(`R2: ${be} is declared on both ${le} and ${z}; leaving it on ${le}.`);continue}t.claimed.set(be,z);let ke=ie.find((Se)=>Se.domain.toLowerCase()===be),De=Ae??"1.2";if(ke&&ke.enabled&&(ke.minTLS??"1.0")===De){if(I.domains.push({domain:be,status:el(ke)}),ke.zoneId)se.set(be,ke.zoneId);continue}await Ss(t,`custom domain ${be} on ${z}`,async()=>{if(ke){if(!k)await m.updateCustomDomain(z,ke.domain,{enabled:!0,minTLS:De},Y);if(Z(`custom domain ${be} updated`,`update custom domain ${be}`),I.domains.push({domain:be,status:el({...ke,enabled:!0})}),ke.zoneId)se.set(be,ke.zoneId);return}let Se=await t.cloudflare.zoneIdFor(be);if(se.set(be,Se),!k)await m.ensureCustomDomain(z,{domain:be,zoneId:Se,minTLS:De},Y,ie);Z(`custom domain ${be} attached`,`attach custom domain ${be}`),I.domains.push({domain:be,status:k?"not attached":"pending"})},()=>I.domains.push({domain:be,status:"error"}))}if(R.cache&&ne.length>0)await If(R,ne.map((be)=>be.domain).filter((be)=>t.claimed.get(be)===z),se,t,Z)}async function If(R,t,m,k,I){let L=Zd(R.cache);if(!L||t.length===0)return;let z=new Map;for(let Y of t){let Z=m.get(Y);if(!Z)try{Z=await k.cloudflare.zoneIdFor(Y)}catch(X){k.warnings.push(`R2: could not resolve the zone for ${Y}, cache rule skipped: ${nl(X)}`);continue}z.set(Z,[...z.get(Z)??[],Y])}for(let Y of z.values()){let Z={action:"set_cache_settings",description:`${kr} ${kf}`,expression:`(${Dr(Y)})`,enabled:!0,action_parameters:L};await Ss(k,`cache rule for ${Y.join(", ")}`,async()=>{let X=await k.cloudflare.getPhaseRules(Y[0],"http_request_cache_settings");if(Qd(X,Z))return;if(!k.dryRun){let ne=await k.cloudflare.putManagedPhaseRules(Y[0],"http_request_cache_settings",[Z]);if(!ne.success)throw Error(ne.message||"cache rule write failed")}I(`cache rule updated for ${Y.join(", ")}`,`update cache rule for ${Y.join(", ")}`)})}}function Zd(R){if(R.edgeTtl===void 0&&R.browserTtl===void 0)return null;let t={cache:!0};if(R.edgeTtl!==void 0)t.edge_ttl={mode:"override_origin",default:R.edgeTtl};if(R.browserTtl!==void 0)t.browser_ttl={mode:"override_origin",default:R.browserTtl};return t}function Qd(R,t){let m=Nr(t.expression),k=Mi(t.expression),I=(Y)=>(Y.description||"").startsWith(kr),L=(Y)=>Y.action===t.action&&Y.description===t.description&&(Y.enabled??!0)===(t.enabled??!0)&&Mi(Y.expression)===k&&ca(Y.action_parameters)===ca(t.action_parameters),z=!1;for(let Y of R){if(!I(Y))continue;let Z=Nr(Y.expression);if(!m.some((ne)=>Z.includes(ne)))continue;if(L(Y)&&m.every((ne)=>Z.includes(ne))&&!z){z=!0;continue}return!1}return z}function Xd(R){let t={id:R.id,enabled:R.enabled??!0,conditions:{prefix:R.prefix??""}};if(R.expireAfterDays!==void 0)t.deleteObjectsTransition={condition:{type:"Age",maxAge:Xc(R.expireAfterDays)}};else if(R.expireOn!==void 0)t.deleteObjectsTransition={condition:{type:"Date",date:R.expireOn}};if(R.abortMultipartUploadsAfterDays!==void 0)t.abortMultipartUploadsTransition={condition:{type:"Age",maxAge:Xc(R.abortMultipartUploadsAfterDays)}};if(R.infrequentAccessAfterDays!==void 0)t.storageClassTransitions=[{storageClass:"InfrequentAccess",condition:{type:"Age",maxAge:Xc(R.infrequentAccessAfterDays)}}];return t}function Xc(R){return Math.round(R*86400)}function Pf(R){let t=new Set,m=[];for(let k of R??[]){let I=typeof k==="string"?{domain:k}:k,L=I.domain?.trim().replace(/\.$/,"").toLowerCase();if(!L||t.has(L))continue;t.add(L),m.push({domain:L,minTLS:I.minTLS})}return m}function el(R){if(!R.enabled)return"disabled";let t=R.status?.ownership,m=R.status?.ssl;if(t==="active"&&m==="active")return"active";for(let k of[t,m])if(k==="error"||k==="blocked"||k==="deactivated")return k;return"pending"}async function Ss(R,t,m,k){try{await m()}catch(I){if(I instanceof Hi)throw I;R.warnings.push(`R2: ${t} failed: ${nl(I)}`),k?.()}}function nl(R){return R instanceof Error?R.message:String(R)}function ca(R){if(Array.isArray(R))return`[${R.map(ca).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${ca(k)}`).join(",")}}`;return JSON.stringify(R)}import{basename as Lf,extname as Ff}from"node:path";import{createHash as xf}from"node:crypto";var Df="https://api.cloudflare.com/client/v4",Gi="TS_CLOUD_CONTENT_HASH",Cs="2025-09-01",il="application/javascript+module",Ef=10007,Tf=[1e4,9109];class _o extends Error{status;errors;constructor(R,t,m=[]){super(R);this.name="WorkersApiError",this.status=t,this.errors=m}hasCode(R){return this.errors.some((t)=>t.code===R)}}class da extends _o{permission;constructor(R,t,m,k=[]){super(`The Cloudflare API token is missing the "${R}" permission (${t}). Edit the token in the Cloudflare dashboard (My Profile, API Tokens), add it, then re-run the deploy.`,m,k);this.name="WorkersPermissionError",this.permission=R}}class ua{name="cloudflare-workers";apiToken;accountId;fetchImpl;constructor(R){if(!R.apiToken)throw Error("Cloudflare Workers needs an API token");if(!R.accountId)throw Error("Cloudflare Workers needs an account id");this.apiToken=R.apiToken,this.accountId=R.accountId,this.fetchImpl=R.fetch??((t,m)=>fetch(t,m))}async request(R,t,m){let k={Authorization:`Bearer ${this.apiToken}`},I;if(m instanceof FormData)I=m;else if(m!==void 0)k["Content-Type"]="application/json",I=JSON.stringify(m);let L=await this.fetchImpl(`${Df}/accounts/${this.accountId}/workers${t}`,{method:R,headers:k,body:I}),z=await L.text(),Y;try{Y=JSON.parse(z)}catch{throw new _o(`Cloudflare Workers API returned ${L.status} with a non-JSON body: ${z.slice(0,200)}`,L.status)}if(!Y.success){let Z=Y.errors??[],X=Z.map((ne)=>`${ne.code}: ${ne.message}`).join(", ");if(Nf(L.status,Z))throw new da(Of(t),`${R} ${t} -> ${L.status}${X?`, ${X}`:""}`,L.status,Z);throw new _o(`Cloudflare Workers API error (${L.status}) on ${R} ${t}: ${X||z.slice(0,200)}`,L.status,Z)}return Y.result}scriptPath(R){return`/scripts/${encodeURIComponent(R)}`}async getSettings(R){try{return await this.request("GET",`${this.scriptPath(R)}/settings`)}catch(t){if(t instanceof da)throw t;if(t instanceof _o&&(t.hasCode(Ef)||t.status===404))return null;throw t}}async getScript(R){return this.getSettings(R)}async uploadModuleScript(R,t){return this.request("PUT",this.scriptPath(R),tu(t))}async ensureModuleScript(R,t){let m=ks(t),k=await this.getSettings(R);if(k&&ma(k,t,m))return{action:"unchanged",hash:m};return await this.uploadModuleScript(R,nu(t,m)),{action:k?"updated":"created",hash:m}}async listCustomDomains(R={}){let t=new URLSearchParams;if(R.service)t.set("service",R.service);if(R.hostname)t.set("hostname",R.hostname);if(R.zoneId)t.set("zone_id",R.zoneId);let m=t.toString(),k=m?`?${m}`:"";return await this.request("GET",`/domains${k}`)??[]}async attachCustomDomain(R,t){let m={hostname:R,service:t.service,environment:t.environment??"production"};if(t.zoneId)m.zone_id=t.zoneId;return this.request("PUT","/domains",m)}async detachCustomDomain(R){await this.request("DELETE",`/domains/${encodeURIComponent(R)}`)}async ensureCustomDomain(R,t,m){let I=(m??await this.listCustomDomains({hostname:R})).find((z)=>z.hostname.toLowerCase()===R.toLowerCase());if(I&&I.service===t.service)return{action:"unchanged",domain:I};if(I)throw Error(`${R} is attached to the Worker '${I.service}'. Detach it there first (Workers & Pages, ${I.service}, Settings, Domains & Routes); ts-cloud does not move it.`);let L=await this.attachCustomDomain(R,t);return{action:"attached",domain:{...L,hostname:L?.hostname||R}}}}function Nf(R,t){if(t.some((m)=>Tf.includes(m.code)))return!0;return(R===401||R===403)&&t.length===0}function Of(R){if(R.startsWith("/domains"))return"Workers Routes: Edit (zone, for Workers custom domains) and Workers Scripts: Edit (account)";return"Workers Scripts: Edit (account)"}function tu(R){if(!R.modules.some((k)=>k.name===R.mainModule))throw Error(`Worker main module '${R.mainModule}' is not one of the uploaded modules`);let t={main_module:R.mainModule,bindings:R.bindings??[],compatibility_date:R.compatibilityDate??Cs,compatibility_flags:R.compatibilityFlags??[],keep_bindings:["secret_text"]},m=new FormData;m.append("metadata",JSON.stringify(t));for(let k of R.modules)m.append(k.name,new Blob([k.content],{type:k.type}),k.name);return m}function ks(R){let t={mainModule:R.mainModule,modules:[...R.modules].sort((m,k)=>m.name.localeCompare(k.name)).map((m)=>({name:m.name,type:m.type,sha256:eu(m.content)})),bindings:[...R.bindings??[]].filter((m)=>m.name!==Gi).sort((m,k)=>m.name.localeCompare(k.name)),compatibilityDate:R.compatibilityDate??Cs,compatibilityFlags:[...R.compatibilityFlags??[]].sort()};return eu(rl(t))}function nu(R,t=ks(R)){return{...R,bindings:[...(R.bindings??[]).filter((m)=>m.name!==Gi),{type:"plain_text",name:Gi,text:t}]}}function ma(R,t,m){let k=R.bindings??[],I=k.find((L)=>L.name===Gi&&L.type==="plain_text");if(!I||I.text!==m)return!1;return(t.bindings??[]).every((L)=>{let z=k.find((Z)=>Z.name===L.name);if(!z||z.type!==L.type)return!1;let Y=L.type==="r2_bucket"?"bucket_name":L.type==="plain_text"?"text":void 0;return!Y||z[Y]===L[Y]})}function eu(R){return xf("sha256").update(R).digest("hex")}function rl(R){if(Array.isArray(R))return`[${R.map(rl).join(",")}]`;if(R&&typeof R==="object")return`{${Object.entries(R).filter(([,m])=>m!==void 0).sort(([m],[k])=>m.localeCompare(k)).map(([m,k])=>`${JSON.stringify(m)}:${rl(k)}`).join(",")}}`;return JSON.stringify(R)}async function ol(R){if(!await Bun.file(R).exists())throw Error(`Worker entry not found: ${R}`);let t;try{t=await Bun.build({entrypoints:[R],target:"browser",format:"esm",minify:!0,external:["cloudflare:*"]})}catch(I){throw Error(`Bundling Worker ${R} failed: ${jf(I)}`)}if(!t.success)throw Error(`Bundling Worker ${R} failed: ${t.logs.map((I)=>String(I.message??I)).join("; ")}`);if(t.outputs.length!==1)throw Error(`Bundling Worker ${R} produced ${t.outputs.length} files (${t.outputs.map((I)=>I.path).join(", ")}); a Worker is uploaded as a single module, so remove the dynamic imports or asset imports that split it.`);let m=t.outputs[0];if(m.kind!=="entry-point")throw Error(`Bundling Worker ${R} produced a ${m.kind} instead of an entry module`);let k=await m.text();return{name:`${Lf(R,Ff(R))}.js`,content:k,type:il,size:new TextEncoder().encode(k).byteLength}}function jf(R){if(R instanceof AggregateError&&R.errors.length>0)return R.errors.map((t)=>t instanceof Error?t.message:String(t?.message??t)).join("; ");return R instanceof Error?R.message:String(R)}import{isAbsolute as Bf,resolve as _f}from"node:path";var Mf="https://api.cloudflare.com/client/v4",zf=/^[a-z0-9][a-z0-9_-]{0,62}$/;async function sl(R,t={}){let m=t.log??(()=>{}),k={workers:[],warnings:[]},I=Object.entries(R.infrastructure?.workers??R.workers??{});if(I.length===0)return m("Workers: none declared, skipping."),k;if(!t.apiToken||!t.accountId){let Y=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),Z=`Workers: ${I.length} Worker(s) declared but ${Y} is not set, skipping.`;return m(Z),k.warnings.push(Z),k}let L=R.infrastructure?.r2??R.r2,z={workers:new ua({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),r2:new Oo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),cloudflare:new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),apiToken:t.apiToken,fetch:t.fetch??((Y,Z)=>fetch(Y,Z)),projectRoot:t.projectRoot??process.cwd(),dryRun:t.dryRun===!0,warnings:k.warnings,log:m,r2ConfigDomains:Gf(L),r2Buckets:L,claimed:new Map};for(let[Y,Z]of I){let X=Z?.name;if(!X||!zf.test(X)){k.warnings.push(`Workers: '${Y}' has an invalid name '${X??""}' (1-63 chars: lowercase letters, digits, '-' and '_'), skipping.`);continue}if(!Z.entry){k.warnings.push(`Workers: ${X} has no entry, skipping.`);continue}m(`Workers: ${z.dryRun?"checking":"reconciling"} ${X}...`);let ne={name:X,changes:[],domains:[]};k.workers.push(ne),await Uf(Z,ne,z);for(let ie of ne.changes)m(`Workers: ${X}: ${ie}`)}return k}async function Uf(R,t,m){let k=R.name,I=Bf(R.entry)?R.entry:_f(m.projectRoot,R.entry),L;try{L=await ol(I)}catch(Y){throw Error(`Worker ${k}: ${zo(Y)}`)}t.changes.push(`bundled ${Jf(L.size)}`);let z={mainModule:L.name,modules:[{name:L.name,content:L.content,type:L.type}],bindings:ru(R,m),compatibilityDate:R.compatibilityDate??Cs,compatibilityFlags:R.compatibilityFlags??[]};if(m.dryRun){let Y=await m.workers.getSettings(k);t.changes.push(Y&&ma(Y,z,ks(z))?"unchanged":"would upload")}else{let{action:Y}=await m.workers.ensureModuleScript(k,z);t.changes.push(Y==="unchanged"?"unchanged":"uploaded")}for(let Y of Kf(R.customDomains))await Wf(k,Y,t,m)}async function Wf(R,t,m,k){let I=(be)=>{m.domains.push({domain:t,status:be})},L=(be)=>{k.warnings.push(`Workers: ${be}`),I("conflict")},z=k.claimed.get(t);if(z&&z!==R){L(`${t} is declared on both ${z} and ${R}; leaving it on ${z}.`);return}k.claimed.set(t,R);let Y=k.r2ConfigDomains.get(t);if(Y){L(`${t} is also declared as a custom domain of the R2 bucket '${Y}' (r2.buckets). A hostname serves either a bucket or a Worker. Remove it from the bucket's customDomains and detach it in the dashboard (R2, ${Y}, Settings, Custom Domains) first; to serve the bucket through the Worker, bind it with bindings.r2Buckets instead.`);return}let Z=await Vf(k);if(Z===null){I("error");return}let X=Z.find((be)=>be.hostname.toLowerCase()===t);if(X?.service===R){I("active");return}if(X){L(`${t} is attached to the Worker '${X.service}'. Detach it there first (Workers & Pages, ${X.service}, Settings, Domains & Routes); it is not moved automatically.`);return}let ne=(await qf(k))?.get(t);if(ne){L(`${t} is attached to the R2 bucket '${ne}' as a custom domain. Detach it first (R2, ${ne}, Settings, Custom Domains, then re-run the deploy); it is not detached automatically. To serve the bucket through the Worker, bind it with bindings.r2Buckets.`);return}let ie;try{ie=await k.cloudflare.zoneIdFor(t)}catch(be){k.warnings.push(`Workers: could not resolve the zone for ${t}, not attached: ${zo(be)}`),I("error");return}let se=await Hf(k,ie,t);if(se.length>0){let be=se.map((Ae)=>`${Ae.type} ${Ae.content}`).join(", ");L(`${t} already has a DNS record (${be}). A Worker custom domain creates its own record, so Cloudflare will not attach over it. Delete the record first (DNS, Records), then re-run the deploy; it is not deleted automatically.`);return}if(k.dryRun){m.changes.push(`would attach custom domain ${t}`),I("not attached");return}try{await k.workers.ensureCustomDomain(t,{service:R,zoneId:ie},Z),m.changes.push(`custom domain ${t} attached`),Z.push({id:"",hostname:t,service:R,zone_id:ie}),I("pending")}catch(be){k.warnings.push(`Workers: custom domain ${t} on ${R} failed: ${zo(be)}`),I("error")}}async function Vf(R){if(R.attached!==void 0)return R.attached;try{R.attached=await R.workers.listCustomDomains()}catch(t){R.warnings.push(`Workers: could not list Worker custom domains, none attached: ${zo(t)}`),R.attached=null}return R.attached}async function qf(R){if(R.r2AccountDomains!==void 0)return R.r2AccountDomains;let t=new Map;try{let m=(await R.r2.listBuckets()).map((k)=>({name:k.name}));for(let k of Object.values(R.r2Buckets?.buckets??{}))if(k.jurisdiction&&k.jurisdiction!=="default")m.push({name:k.name,jurisdiction:k.jurisdiction});for(let k of m){let I=await R.r2.listCustomDomains(k.name,{jurisdiction:k.jurisdiction}).catch(()=>[]);for(let L of I)t.set(L.domain.toLowerCase(),k.name)}R.r2AccountDomains=t}catch(m){R.log(`Workers: could not check R2 custom domains (${zo(m)}); relying on the DNS check.`),R.r2AccountDomains=null}return R.r2AccountDomains}async function Hf(R,t,m){try{let k=await R.fetch(`${Mf}/zones/${t}/dns_records?name=${encodeURIComponent(m)}&per_page=100`,{method:"GET",headers:{Authorization:`Bearer ${R.apiToken}`}}),I=await k.json();if(!I?.success)throw Error(`HTTP ${k.status}`);return(I.result??[]).filter((L)=>L.name?.toLowerCase()===m).map((L)=>({type:L.type??"?",content:L.content??""}))}catch(k){return R.log(`Workers: could not read DNS records for ${m} (${zo(k)}); attaching anyway.`),[]}}function ru(R,t){let m=[],k=new Set,I=(z)=>{if(z===Gi)return t.warnings.push(`Workers: ${R.name}: binding name ${Gi} is reserved for ts-cloud, ignored.`),!1;if(k.has(z))return t.warnings.push(`Workers: ${R.name}: binding ${z} is declared twice; the first one wins.`),!1;return k.add(z),!0},L=new Map;for(let z of Object.values(t.r2Buckets?.buckets??{}))if(z.jurisdiction&&z.jurisdiction!=="default")L.set(z.name,z.jurisdiction);for(let[z,Y]of Object.entries(R.bindings?.r2Buckets??{})){if(!I(z))continue;let Z=L.get(Y);m.push(Z?{type:"r2_bucket",name:z,bucket_name:Y,jurisdiction:Z}:{type:"r2_bucket",name:z,bucket_name:Y})}for(let[z,Y]of Object.entries(R.bindings?.vars??{}))if(I(z))m.push({type:"plain_text",name:z,text:String(Y)});return m}function Gf(R){let t=new Map;for(let m of Object.values(R?.buckets??{}))for(let k of m?.customDomains??[]){let I=iu(typeof k==="string"?k:k.domain);if(I)t.set(I,m.name)}return t}function Kf(R){return[...new Set((R??[]).map(iu).filter(Boolean))]}function iu(R){return(R??"").trim().replace(/\.$/,"").toLowerCase()}function Jf(R){if(R<1024)return`${R} B`;if(R<1048576)return`${(R/1024).toFixed(1)} KB`;return`${(R/1024/1024).toFixed(1)} MB`}function zo(R){return R instanceof Error?R.message:String(R)}async function eg(R){let t=la();if(t.emptyEnvKey||t.emptyEnvSecret)a("Empty AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY env var detected — likely a misconfigured .env file. Remove the empty lines or fill them in.");e(`AWS credentials: ${t.description}`);try{let k=await new bt(R).getCallerIdentity();if(k.Arn)e(`AWS identity: ${k.Arn}`)}catch(m){a(`Could not verify AWS identity: ${m.message}`)}}function tg(){try{return dl("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function al(R,t,m,k){let{ensureManagementDashboard:I}=await import("./chunk-7477zgt9.js");I(R,{logger:{info:e,warn:a}});let L=R.sites||{},z=Object.entries(L);if(z.length===0)return a("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(k&&!L[k])return r(`Site '${k}' was not found. Configured sites: ${z.map(([De])=>De).join(", ")}`),!1;let Y=z.filter(([De,Se])=>{if(!Se)return!1;if(k&&De!==k)return!1;if(A(Se)==="bucket")return a(`Site '${De}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return js(Se)});if(k)e(`Deploying only '${k}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let Z=R.project.slug,ne=(R.infrastructure?.compute||{}).runtime||"bun",ie=O({config:R}),se=tg(),be=new Map,Ae=new Map,le={step:(De)=>u(De),error:(De)=>r(De)};if(!await vs(R,"beforeDeploy",le))return!1;if(!await vs(R,"beforeBuild",le))return!1;for(let[De,Se]of Y){let Re=A(Se);if(i(`Preparing site: ${De}`),e(`Domain: ${Se.domain||"(none)"}`),e(`Source: ${Se.root}`),e(`Kind: ${Re==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),Re==="server-app")e(`Start: ${Se.start}`),e(`Port: ${Se.port??"(unset)"}`);if(Se.build){u(`Running build: ${Se.build}`);try{dl(Se.build,{stdio:"inherit",cwd:process.cwd()})}catch(Ve){return r(`Build failed for site '${De}': ${Ve.message}`),!1}}let Pe=Gd({root:Se.root,siteName:De,expectIndex:Re==="server-static"});for(let Ve of Pe)if(Ve.level==="error")r(Ve.message);else a(Ve.message);if(Pe.some((Ve)=>Ve.level==="error"))return!1;let ze=Se.build?void 0:JSON.stringify([Xf(Se.root),[...Se.exclude||[]].sort()]),Le=ze?Ae.get(ze):void 0;if(Le){u(`Reusing package for ${Se.root} → ${Le}`),be.set(De,Le);continue}let Be=lu(cu(),`${Z}-${De}-${se}.tar.gz`);u(`Packaging ${Se.root} → ${Be}`);try{let Ve=(Se.exclude||[]).map((ct)=>`--exclude=${ct}`);Yf("tar",["czf",Be,"-C",Se.root,...Ve,"."],{stdio:"inherit",env:{...process.env,COPYFILE_DISABLE:"1"}})}catch(Ve){return r(`Failed to package '${De}': ${Ve.message}`),!1}if(be.set(De,Be),ze)Ae.set(ze,Be)}if(!await vs(R,"afterBuild",le))return!1;let ke=await Eo({config:k?{...R,sites:Object.fromEntries(Y)}:R,rpxConfig:k?R:void 0,environment:t,driver:ie,sha:se,runtime:ne,tarballForSite:(De)=>{let Se=be.get(De);if(!Se)throw Error(`Missing tarball for site '${De}'`);return Se},logger:{info:(De)=>e(De),warn:(De)=>a(De),error:(De)=>r(De),step:(De)=>u(De),success:(De)=>n(De)}});if(ke&&!await vs(R,"afterDeploy",le))return!1;return ke}async function pa(R){let t=new Yr;if(u("Running pre-deployment security scan..."),R.exclude?.length)e(`Excluding from the scan: ${R.exclude.join(", ")}`);let m=await t.scan({directory:R.sourceDir,failOnSeverity:R.failOnSeverity||"critical",skipPatterns:R.skipPatterns,exclude:R.exclude});return{passed:m.passed,result:m}}function ng(){let R=lu(cu(),`ts-cloud-empty-scan-${process.pid}`);return au(R,{recursive:!0}),R}function fa(R){let{summary:t,findings:m,scannedFiles:k,duration:I}=R;if(e(`
376
376
  Scanned ${k} files in ${I}ms`),t.critical>0)r(` Critical: ${t.critical}`);else e(` Critical: ${t.critical}`);if(t.high>0)a(` High: ${t.high}`);else e(` High: ${t.high}`);if(e(` Medium: ${t.medium}`),e(` Low: ${t.low}`),m.length>0){e(`
377
377
  Findings:`);let L=m.filter((ne)=>ne.pattern.severity==="critical"),z=m.filter((ne)=>ne.pattern.severity==="high"),Y=m.filter((ne)=>ne.pattern.severity==="medium"),Z=m.filter((ne)=>ne.pattern.severity==="low"),X=(ne,ie,se)=>{if(ne.length>0){console.log(`
378
378
  ${Kt(`[${ie}]`,se)}`);for(let be of ne.slice(0,10))e(` ${be.pattern.name}`),e(` File: ${be.file}:${be.line}`),e(` Match: ${be.match}`);if(ne.length>10)e(` ... and ${ne.length-10} more ${ie.toLowerCase()} findings`)}};X(L,"CRITICAL","red"),X(z,"HIGH","yellow"),X(Y,"MEDIUM","blue"),X(Z,"LOW","gray")}}function du(R,t){let m=Object.keys(R.environments??{});if(t&&m.includes(t))return t;if(m.includes("production"))return"production";if(m[0])return m[0];throw Error("A configured environment is required for security policy evaluation")}function cl(R,t,m){let k=du(R,t),I=y(process.cwd(),R);try{let L=new Ut(I.store);ai(I);let z=ue(I,k);if(m)gc(L,z,m);else fc(L,z);let Y=gr(L,{scope:z,desiredConfigHash:I.project.desiredConfigHash});return e(`Security policy: ${Y.decision.policyId} v${Y.decision.policyVersion} — ${Y.decision.outcome.toUpperCase()}`),e(`Security decision: ${Y.decision.explanation}`),{allowed:Y.decision.outcome!=="block",explanation:Y.decision.explanation}}finally{I.store.close()}}async function rg(R,t){let m=du(R),k=y(process.cwd(),R);try{let I=new Ut(k.store);ai(k);let L=ue(k,m),z=t.imageSha256?`${t.imageRef}@sha256:${t.imageSha256.replace(/^sha256:/,"")}`:t.imageRef;u("Scanning the built image and producing release security artifacts...");let Y=await hc(I,{scope:L,releaseId:z,imageRef:t.imageRef,imageSha256:t.imageSha256,artifactRoot:t.artifactRoot,invocationId:t.invocationId,startedAt:t.startedAt,externalParameters:{imageRef:t.imageRef,artifactRoot:t.artifactRoot}});e(`Image scanner: ${Y.scan.run.status} (${Y.scan.findings.length} findings)`),e(`Release SBOM: ${Y.sbomSource==="image"?"full image inventory":Y.sbomSource==="manifest"?"package-manifest fallback":"unavailable"}`);let Z=gr(I,{scope:L,operationId:t.invocationId,desiredConfigHash:k.project.desiredConfigHash});return e(`Release policy: ${Z.decision.policyId} v${Z.decision.policyVersion} — ${Z.decision.outcome.toUpperCase()}`),e(`Release decision: ${Z.decision.explanation}`),{allowed:Z.decision.outcome!=="block",explanation:Z.decision.explanation}}finally{k.store.close()}}function ig(R){try{let t=y(process.cwd(),R),m=new or(t.store).current();if(!m.attackMode&&!m.mitigationPause&&m.ipRules.allow.length===0&&m.ipRules.block.length===0)return R;let k=ds(R,m);return e(`Applying protection controls: ${m.ipRules.allow.length} allow, ${m.ipRules.block.length} block${m.attackMode?", attack mode ON":""}${m.mitigationPause?", mitigation PAUSED":""}`),k}catch{return R}}function ul(R){R.command("deploy:security-scan","Run pre-deployment security scan").option("--source <path>","Source directory to scan",{default:"."}).option("--fail-on <severity>","Fail on severity level (critical, high, medium, low)",{default:"critical"}).option("--skip-patterns <patterns>","Comma-separated list of pattern names to skip").action(async(t)=>{i("Pre-Deployment Security Scan");try{let m=t?.source||".",k=t?.failOn||"critical",I=t?.skipPatterns?.split(",").map((Y)=>Y.trim())||[];if(!In(m)){r(`Source directory not found: ${m}`);return}e(`Source: ${m}`),e(`Fail on: ${k} or higher severity`);let{passed:L,result:z}=await pa({sourceDir:m,failOnSeverity:k,skipPatterns:I});if(fa(z),L)n(`
@@ -382,9 +382,9 @@ Recommendations:`),e(" 1. Remove any hardcoded credentials from your code"),e("
382
382
  ✗ Deployment configuration is invalid:`);for(let it of Y)r(` • ${it}`);process.exitCode=1;return}if(t?.dryRun){if(t.site&&!z.sites?.[t.site]){r(`Site '${t.site}' was not found. Configured sites: ${Object.keys(z.sites||{}).join(", ")||"none"}`),process.exitCode=1;return}let it=H(z),Et=t.stack||T(z,k),hn=U(z),yn=z.project.region||"us-east-1",tr=t.site?[t.site]:Object.keys(z.sites||{});i("Deployment Plan"),e(`Cloud provider: ${hn}`),e(`Mode: ${it}`),e(`Stack: ${Et}`),e(`Region: ${yn}`),e(`Environment: ${k}`),e(`Sites: ${tr.length>0?tr.join(", "):"none"}`),await ou(z,{dryRun:!0}),await su(z,{dryRun:!0}),n("Dry run complete. No infrastructure, DNS, certificates, or application files were changed.");return}if(U(z)==="aws"){let it=z.project?.region||"us-east-1";await eg(it)}let X;if(!t?.skipSecurityScan){let it=Kc(z,t?.site);if(!it)e("This deploy ships no files — every site in scope is a redirect or proxy route, so only gateway routes and certificates change. Scanning an empty artifact.");let{result:Et}=await pa({sourceDir:it?process.cwd():ng(),failOnSeverity:t?.securityFailOn||"critical",exclude:z.infrastructure?.security?.scan?.exclude});fa(Et),X=Et}else a(`Security scan skipped (--skip-security-scan)
383
383
  `);let ne=cl(z,k,X);if(!ne.allowed){r(`
384
384
  ✗ Deployment blocked by security policy: ${ne.explanation}`),e("Remediate the findings or create an authorized, time-limited waiver in the Security posture center."),process.exitCode=1;return}if(n(`✓ Security policy allows this deployment
385
- `),!await ou(z)){process.exitCode=1;return}if(!await su(z)){process.exitCode=1;return}if(H(z)==="serverless"){u("Serverless project detected: deploying the Lambda application");let{deployServerlessApp:it}=await import("./chunk-6ybjfjbc.js");await it(z,k,{}),n("Serverless deployment complete");return}let ie=t?.stack||T(z,k),se=z.project.region||"us-east-1",be=z.infrastructure?.deployStack!==!1,Ae=z.sites&&Object.keys(z.sites).length>0,le=z.infrastructure?.dns?.provider;if(Ae&&le){if(await lg(z,t?.site,le,se,t?.skipDnsVerification,k,m),!be){if(z.infrastructure?.compute){let it=Object.values(z.sites).map((Et)=>Et.domain).filter((Et)=>!!Et);if(it.length>0)u("Syncing CloudFront dynamic HTTP methods for app domains..."),await ta(it)}return}}if(!be){e("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let ke=U(z);if(e(`Cloud provider: ${ke}`),e(`Stack: ${ie}`),e(`Region: ${se}`),e(`Environment: ${k}`),(ke==="hetzner"||z.infrastructure?.compute?.mode==="server")&&Io(z)){u(`Provisioning ${ke} compute infrastructure...`);let it=O({config:z,provider:ke});if(!it.provisionComputeInfrastructure){r(`${ke} driver does not support compute provisioning`),process.exitCode=1;return}let Et=await it.provisionComputeInfrastructure({config:z,environment:k});if(n(`${ke} compute infrastructure ready`),Et.appPublicIp)e(`App server: ${Et.appPublicIp}`);if(Et.appInstanceId)e(`Server ID: ${Et.appInstanceId}`);if(!await al(z,k,se,t?.site))r(`App deploy to ${ke} compute reported a failure`),process.exitCode=1;else{if(n(`App deployed to ${ke} compute`),t?.skipDnsVerification)e("DNS verification and record reconciliation skipped (--skip-dns-verification)");else await sg(z,Et.appPublicIp,le,Et.appPublicIpv6),await ag(z,le);let yn=await wo({config:z,environment:k,driver:it,logger:{info:e,warn:a,error:r,step:u,success:n}});if(!yn)r("App deployed, but rpx TLS certificate reconciliation failed");if(!yn)process.exitCode=1;if(!t?.skipDnsVerification)await cg(z,Et.appPublicIp,Et.appPublicIpv6)}return}u("Generating CloudFormation template...");let Se=new Ro({config:z,environment:k});Se.generate();let Re=Se.toJSON(),Pe=JSON.parse(Re);if(Object.keys(Pe.Resources||{}).length===0){e(`No infrastructure resources to deploy for environment '${k}' — skipping stack ${ie}.`);return}u("Validating template...");let Le=ts(Pe),Be=is(Re),Ve=os(Pe),ct=[...Le.errors,...Be.errors,...Ve.errors];if(ct.length>0){r("Template validation failed:");for(let it of ct)r(` - ${it.path}: ${it.message}`);return}let Dt=[...Le.warnings,...Be.warnings,...Ve.warnings];if(Dt.length>0)for(let it of Dt)a(` - ${it.path}: ${it.message}`);n("Template validated successfully");let nt=Object.keys(Pe.Resources).length;e(`
385
+ `),!await ou(z)){process.exitCode=1;return}if(!await su(z)){process.exitCode=1;return}if(H(z)==="serverless"){u("Serverless project detected: deploying the Lambda application");let{deployServerlessApp:it}=await import("./chunk-8dzqjsz1.js");await it(z,k,{}),n("Serverless deployment complete");return}let ie=t?.stack||T(z,k),se=z.project.region||"us-east-1",be=z.infrastructure?.deployStack!==!1,Ae=z.sites&&Object.keys(z.sites).length>0,le=z.infrastructure?.dns?.provider;if(Ae&&le){if(await lg(z,t?.site,le,se,t?.skipDnsVerification,k,m),!be){if(z.infrastructure?.compute){let it=Object.values(z.sites).map((Et)=>Et.domain).filter((Et)=>!!Et);if(it.length>0)u("Syncing CloudFront dynamic HTTP methods for app domains..."),await ta(it)}return}}if(!be){e("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let ke=U(z);if(e(`Cloud provider: ${ke}`),e(`Stack: ${ie}`),e(`Region: ${se}`),e(`Environment: ${k}`),(ke==="hetzner"||z.infrastructure?.compute?.mode==="server")&&Io(z)){u(`Provisioning ${ke} compute infrastructure...`);let it=O({config:z,provider:ke});if(!it.provisionComputeInfrastructure){r(`${ke} driver does not support compute provisioning`),process.exitCode=1;return}let Et=await it.provisionComputeInfrastructure({config:z,environment:k});if(n(`${ke} compute infrastructure ready`),Et.appPublicIp)e(`App server: ${Et.appPublicIp}`);if(Et.appInstanceId)e(`Server ID: ${Et.appInstanceId}`);if(!await al(z,k,se,t?.site))r(`App deploy to ${ke} compute reported a failure`),process.exitCode=1;else{if(n(`App deployed to ${ke} compute`),t?.skipDnsVerification)e("DNS verification and record reconciliation skipped (--skip-dns-verification)");else await sg(z,Et.appPublicIp,le,Et.appPublicIpv6),await ag(z,le);let yn=await wo({config:z,environment:k,driver:it,logger:{info:e,warn:a,error:r,step:u,success:n}});if(!yn)r("App deployed, but rpx TLS certificate reconciliation failed");if(!yn)process.exitCode=1;if(!t?.skipDnsVerification)await cg(z,Et.appPublicIp,Et.appPublicIpv6)}return}u("Generating CloudFormation template...");let Se=new Ro({config:z,environment:k});Se.generate();let Re=Se.toJSON(),Pe=JSON.parse(Re);if(Object.keys(Pe.Resources||{}).length===0){e(`No infrastructure resources to deploy for environment '${k}' — skipping stack ${ie}.`);return}u("Validating template...");let Le=ts(Pe),Be=is(Re),Ve=os(Pe),ct=[...Le.errors,...Be.errors,...Ve.errors];if(ct.length>0){r("Template validation failed:");for(let it of ct)r(` - ${it.path}: ${it.message}`);return}let Dt=[...Le.warnings,...Be.warnings,...Ve.warnings];if(Dt.length>0)for(let it of Dt)a(` - ${it.path}: ${it.message}`);n("Template validated successfully");let nt=Object.keys(Pe.Resources).length;e(`
386
386
  Resources to deploy: ${nt}`);let xt={};for(let it of Object.values(Pe.Resources)){let Et=it.Type;xt[Et]=(xt[Et]||0)+1}for(let[it,Et]of Object.entries(xt).sort((hn,yn)=>yn[1]-hn[1]).slice(0,5))e(` - ${it}: ${Et}`);if(!(m||await d(`
387
- Deploy now?`,!0))){e("Deployment cancelled");return}let Tt=new v(se),Ge=Ia(Pe);if(Ge.length>0){let{ensureFailoverReplicaBuckets:it}=await import("./chunk-zg8nnq7k.js");u("Ensuring failover replica buckets..."),await it(Ge,(Et)=>e(` ${Et}`))}u("Checking stack status...");let Ot=!1;try{let it=await Tt.describeStacks({stackName:ie});Ot=it.Stacks&&it.Stacks.length>0}catch(it){Ot=!1}if(Ot){e("Stack exists, updating...");let it=new s("Updating CloudFormation stack...");it.start();try{await Tt.updateStack({stackName:ie,templateBody:Re,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:z.project.name},{Key:"Environment",Value:k},{Key:"ManagedBy",Value:"ts-cloud"}]}),it.succeed("Update initiated"),u("Waiting for stack update to complete..."),await Tt.waitForStack(ie,"stack-update-complete"),n("Stack updated successfully!")}catch(Et){if(Et.message.includes("No updates are to be performed"))it.succeed("No changes detected"),e("Stack is already up to date — continuing to app deploy");else throw Et}}else{e("Creating new stack...");let it=new s("Creating CloudFormation stack...");it.start(),await Tt.createStack({stackName:ie,templateBody:Re,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:z.project.name},{Key:"Environment",Value:k},{Key:"ManagedBy",Value:"ts-cloud"}]}),it.succeed("Stack creation initiated"),u("Waiting for stack creation to complete..."),await Tt.waitForStack(ie,"stack-create-complete"),n("Stack created successfully!")}let zt=await Tt.getStackOutputs(ie);if(Ee(`Deployment Complete!
387
+ Deploy now?`,!0))){e("Deployment cancelled");return}let Tt=new v(se),Ge=Ia(Pe);if(Ge.length>0){let{ensureFailoverReplicaBuckets:it}=await import("./chunk-kvwm9z1r.js");u("Ensuring failover replica buckets..."),await it(Ge,(Et)=>e(` ${Et}`))}u("Checking stack status...");let Ot=!1;try{let it=await Tt.describeStacks({stackName:ie});Ot=it.Stacks&&it.Stacks.length>0}catch(it){Ot=!1}if(Ot){e("Stack exists, updating...");let it=new s("Updating CloudFormation stack...");it.start();try{await Tt.updateStack({stackName:ie,templateBody:Re,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:z.project.name},{Key:"Environment",Value:k},{Key:"ManagedBy",Value:"ts-cloud"}]}),it.succeed("Update initiated"),u("Waiting for stack update to complete..."),await Tt.waitForStack(ie,"stack-update-complete"),n("Stack updated successfully!")}catch(Et){if(Et.message.includes("No updates are to be performed"))it.succeed("No changes detected"),e("Stack is already up to date — continuing to app deploy");else throw Et}}else{e("Creating new stack...");let it=new s("Creating CloudFormation stack...");it.start(),await Tt.createStack({stackName:ie,templateBody:Re,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:z.project.name},{Key:"Environment",Value:k},{Key:"ManagedBy",Value:"ts-cloud"}]}),it.succeed("Stack creation initiated"),u("Waiting for stack creation to complete..."),await Tt.waitForStack(ie,"stack-create-complete"),n("Stack created successfully!")}let zt=await Tt.getStackOutputs(ie);if(Ee(`Deployment Complete!
388
388
 
389
389
  Stack: ${ie}
390
390
  Region: ${se}
@@ -393,16 +393,16 @@ Resources: ${nt}
393
393
 
394
394
  View in console:
395
395
  https://console.aws.amazon.com/cloudformation/home?region=${se}#/stacks/stackinfo?stackId=${encodeURIComponent(ie)}`,"green"),Object.keys(zt).length>0){e(`
396
- Stack Outputs:`);for(let[it,Et]of Object.entries(zt))e(` - ${it}: ${Et}`)}if(Ge.length>0){let{grantFailoverReplicaAccess:it}=await import("./chunk-zg8nnq7k.js");u("Granting the distribution read access to its failover replicas..."),await it(Ge,zt,(Et)=>e(` ${Et}`))}if(z.infrastructure?.storage)for(let[it,Et]of Object.entries(z.infrastructure.storage)){if(!Et.website||!Et.root)continue;let hn=zt[`${it}BucketName`]||zt.FrontendBucketName,yn=zt[`${it}CloudFrontDistributionId`];if(!hn){a(`Could not find bucket name for storage '${it}' — skipping file upload`);continue}if(!In(Et.root)){a(`Source directory not found: ${Et.root} — skipping file upload for '${it}'`);continue}u(`Uploading files from ${Et.root} to s3://${hn}...`);let{uploadStaticFiles:tr,invalidateCache:Oi}=await import("./chunk-hp1cqk45.js"),wn=await tr({sourceDir:Et.root,bucket:hn,region:se,onProgress:(Wt,Pn,xn)=>{if(Wt%10===0||Wt===Pn)e(` ${Wt}/${Pn}: ${xn}`)}});if(wn.errors.length>0)a(`Upload completed with errors: ${wn.errors.join(", ")}`);else{let Wt=wn.skipped>0?`Uploaded ${wn.uploaded} files (${wn.skipped} unchanged)`:`Uploaded ${wn.uploaded} files`;n(Wt)}if(yn&&wn.uploaded>0){u("Invalidating CloudFront cache...");let{invalidationId:Wt}=await Oi(yn);n(`Cache invalidation created: ${Wt}`)}}if(Ge.length>0){let{seedFailoverReplicas:it}=await import("./chunk-zg8nnq7k.js");u("Syncing failover replicas..."),await it(Ge,(Et)=>e(` ${Et}`))}if(z.infrastructure?.compute)await al(z,k,se,t?.site);if(z.infrastructure?.compute&&z.sites){let it=Object.values(z.sites).map((Et)=>Et.domain).filter((Et)=>!!Et);if(it.length>0)u("Syncing CloudFront dynamic HTTP methods for app domains..."),await ta(it)}}catch(L){if(r(`Deployment failed: ${L.message}`),process.exitCode=1,L.stack)e(`
396
+ Stack Outputs:`);for(let[it,Et]of Object.entries(zt))e(` - ${it}: ${Et}`)}if(Ge.length>0){let{grantFailoverReplicaAccess:it}=await import("./chunk-kvwm9z1r.js");u("Granting the distribution read access to its failover replicas..."),await it(Ge,zt,(Et)=>e(` ${Et}`))}if(z.infrastructure?.storage)for(let[it,Et]of Object.entries(z.infrastructure.storage)){if(!Et.website||!Et.root)continue;let hn=zt[`${it}BucketName`]||zt.FrontendBucketName,yn=zt[`${it}CloudFrontDistributionId`];if(!hn){a(`Could not find bucket name for storage '${it}' — skipping file upload`);continue}if(!In(Et.root)){a(`Source directory not found: ${Et.root} — skipping file upload for '${it}'`);continue}u(`Uploading files from ${Et.root} to s3://${hn}...`);let{uploadStaticFiles:tr,invalidateCache:Oi}=await import("./chunk-hp1cqk45.js"),wn=await tr({sourceDir:Et.root,bucket:hn,region:se,onProgress:(Wt,Pn,xn)=>{if(Wt%10===0||Wt===Pn)e(` ${Wt}/${Pn}: ${xn}`)}});if(wn.errors.length>0)a(`Upload completed with errors: ${wn.errors.join(", ")}`);else{let Wt=wn.skipped>0?`Uploaded ${wn.uploaded} files (${wn.skipped} unchanged)`:`Uploaded ${wn.uploaded} files`;n(Wt)}if(yn&&wn.uploaded>0){u("Invalidating CloudFront cache...");let{invalidationId:Wt}=await Oi(yn);n(`Cache invalidation created: ${Wt}`)}}if(Ge.length>0){let{seedFailoverReplicas:it}=await import("./chunk-kvwm9z1r.js");u("Syncing failover replicas..."),await it(Ge,(Et)=>e(` ${Et}`))}if(z.infrastructure?.compute)await al(z,k,se,t?.site);if(z.infrastructure?.compute&&z.sites){let it=Object.values(z.sites).map((Et)=>Et.domain).filter((Et)=>!!Et);if(it.length>0)u("Syncing CloudFront dynamic HTTP methods for app domains..."),await ta(it)}}catch(L){if(r(`Deployment failed: ${L.message}`),process.exitCode=1,L.stack)e(`
397
397
  Stack trace:`),console.error(L.stack)}finally{if(I)await I()}}),R.command("deploy:server","Deploy EC2 infrastructure").option("--env <environment>","Environment (production, staging, development)").option("--site <name>","Deploy specific site only (routes are still regenerated in full)").action(async(t)=>{i("Deploying Server Infrastructure");try{let m=await Ne(),k=t?.env||"production",I=m.project.region||"us-east-1",L=Fr(m);if(L){r(L),process.exitCode=1;return}if(!Io(m)){r("No `infrastructure.compute` configured — nothing to deploy as a server."),e("Add an EC2 compute block to cloud.config, or use `cloud deploy:serverless` for Lambda apps."),process.exitCode=1;return}if(e(`Region: ${I}`),e(`Environment: ${k}`),!await al(m,k,I,t?.site)){process.exitCode=1;return}if(m.sites){let Y=Object.values(m.sites).map((Z)=>Z.domain).filter((Z)=>!!Z);if(Y.length>0)u("Syncing CloudFront dynamic HTTP methods for app domains..."),await ta(Y)}n(`
398
- Server deployment complete!`)}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),R.command("deploy:serverless","Deploy a serverless application (http/queue/cli Lambda functions)").option("--env <environment>","Environment (production, staging, development)").option("--skip-build","Skip local build hooks").option("--skip-hooks","Skip remote deploy hooks (e.g. migrations)").option("--redeploy","Re-activate the last build without rebuilding").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",I=Fr(m);if(I){r(I),process.exitCode=1;return}let{deployServerlessApp:L,redeployServerlessApp:z}=await import("./chunk-6ybjfjbc.js");if(t?.redeploy){await z(m,k);return}await L(m,k,{skipBuild:t?.skipBuild,skipDeployHooks:t?.skipHooks})}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),R.command("serverless:rollback","Roll back a serverless app to the previous build").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",{rollbackServerlessApp:I}=await import("./chunk-6ybjfjbc.js");await I(m,k)}catch(m){r(`Rollback failed: ${m.message}`),process.exitCode=1}}),R.command("deploy:rollback [site]","Roll a compute site back to a previous release").option("--env <environment>","Environment (production, staging, development)").option("--to <release>","Release id to roll back to (default: the previous release)").option("--dry-run","Say which release it would roll back to, and change nothing").option("--all","Every configured site, instead of one").option("--only-if-live <release>","Only roll back a site whose live release is this commit (what a failed deploy switched)").action(async(t,m)=>{i("Rolling Back Release");try{let k=await Ne(),I=m?.env||"production",L=m?.all?Object.keys(k.sites||{}):[t||Object.keys(k.sites||{})[0]].filter(Boolean);if(L.length===0){r("No site configured to roll back."),process.exitCode=1;return}let{rollbackComputeSite:z}=await import("./chunk-9nen8018.js"),Y=O({config:k});for(let Z of L){let X=await z({driver:Y,slug:k.project.slug,environment:I,logger:f},{siteName:Z,to:m?.to,dryRun:m?.dryRun,onlyIfLive:m?.onlyIfLive,site:k.sites?.[Z]});for(let ne of X.perInstance||[])e(` ${Z} ${ne.instanceId}: ${ne.output?.trim()||ne.status}`);if(!X.success)r(`Rollback of ${Z} failed: ${X.error||"unknown error"}`),process.exitCode=1}}catch(k){r(`Rollback failed: ${k.message}`),process.exitCode=1}}),R.command("deploy:history [site]","Show a compute site's deployment history").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Number of entries to show",{default:"20"}).action(async(t,m)=>{i("Deployment History");try{let k=await Ne(),I=m?.env||"production",L=t||Object.keys(k.sites||{})[0];if(!L){r("No site configured."),process.exitCode=1;return}let{getComputeDeployHistory:z}=await import("./chunk-9nen8018.js"),Y=await z({driver:O({config:k}),slug:k.project.slug,environment:I,logger:f},{siteName:L,limit:Number.parseInt(m?.limit||"20",10)||20});if(!Y.success){r(`Could not read history: ${Y.error||"unknown error"}`),process.exitCode=1;return}for(let Z of Y.perInstance||[])e(`
398
+ Server deployment complete!`)}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),R.command("deploy:serverless","Deploy a serverless application (http/queue/cli Lambda functions)").option("--env <environment>","Environment (production, staging, development)").option("--skip-build","Skip local build hooks").option("--skip-hooks","Skip remote deploy hooks (e.g. migrations)").option("--redeploy","Re-activate the last build without rebuilding").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",I=Fr(m);if(I){r(I),process.exitCode=1;return}let{deployServerlessApp:L,redeployServerlessApp:z}=await import("./chunk-8dzqjsz1.js");if(t?.redeploy){await z(m,k);return}await L(m,k,{skipBuild:t?.skipBuild,skipDeployHooks:t?.skipHooks})}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),R.command("serverless:rollback","Roll back a serverless app to the previous build").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",{rollbackServerlessApp:I}=await import("./chunk-8dzqjsz1.js");await I(m,k)}catch(m){r(`Rollback failed: ${m.message}`),process.exitCode=1}}),R.command("deploy:rollback [site]","Roll a compute site back to a previous release").option("--env <environment>","Environment (production, staging, development)").option("--to <release>","Release id to roll back to (default: the previous release)").option("--dry-run","Say which release it would roll back to, and change nothing").option("--all","Every configured site, instead of one").option("--only-if-live <release>","Only roll back a site whose live release is this commit (what a failed deploy switched)").action(async(t,m)=>{i("Rolling Back Release");try{let k=await Ne(),I=m?.env||"production",L=m?.all?Object.keys(k.sites||{}):[t||Object.keys(k.sites||{})[0]].filter(Boolean);if(L.length===0){r("No site configured to roll back."),process.exitCode=1;return}let{rollbackComputeSite:z}=await import("./chunk-4kt2sgqk.js"),Y=O({config:k});for(let Z of L){let X=await z({driver:Y,slug:k.project.slug,environment:I,logger:f},{siteName:Z,to:m?.to,dryRun:m?.dryRun,onlyIfLive:m?.onlyIfLive,site:k.sites?.[Z]});for(let ne of X.perInstance||[])e(` ${Z} ${ne.instanceId}: ${ne.output?.trim()||ne.status}`);if(!X.success)r(`Rollback of ${Z} failed: ${X.error||"unknown error"}`),process.exitCode=1}}catch(k){r(`Rollback failed: ${k.message}`),process.exitCode=1}}),R.command("deploy:history [site]","Show a compute site's deployment history").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Number of entries to show",{default:"20"}).action(async(t,m)=>{i("Deployment History");try{let k=await Ne(),I=m?.env||"production",L=t||Object.keys(k.sites||{})[0];if(!L){r("No site configured."),process.exitCode=1;return}let{getComputeDeployHistory:z}=await import("./chunk-4kt2sgqk.js"),Y=await z({driver:O({config:k}),slug:k.project.slug,environment:I,logger:f},{siteName:L,limit:Number.parseInt(m?.limit||"20",10)||20});if(!Y.success){r(`Could not read history: ${Y.error||"unknown error"}`),process.exitCode=1;return}for(let Z of Y.perInstance||[])e(`
399
399
  ${Z.instanceId}:`),e(Z.output?.trimEnd()||"(no output)")}catch(k){r(`History lookup failed: ${k.message}`),process.exitCode=1}}),R.command("deploy:recipe <name> <script>","Run a reusable server recipe (a local bash file) across servers").option("--env <environment>","Environment (production, staging, development)").option("--user <user>","User to run the recipe as",{default:"root"}).action(async(t,m,k)=>{i(`Running Recipe: ${t}`);try{if(!In(m)){r(`Recipe script not found: ${m}`),process.exitCode=1;return}let I=await Ne(),L=k?.env||"production",z=ll(m,"utf8").split(`
400
- `),{runComputeRecipe:Y}=await import("./chunk-9nen8018.js"),Z=await Y({driver:O({config:I}),slug:I.project.slug,environment:L,logger:f},{name:t,script:z,user:k?.user});for(let X of Z.perInstance||[])e(`
401
- ${X.instanceId}:`),e(X.output?.trimEnd()||"(no output)");if(!Z.success)process.exitCode=1}catch(I){r(`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(t,m)=>{i("Database Restore");try{let k=await Ne(),I=m?.env||"production",{restoreDatabaseBackup:L}=await import("./chunk-9nen8018.js"),z=await L({driver:O({config:k}),slug:k.project.slug,environment:I,logger:f},{database:w(k),from:t});for(let Y of z.perInstance||[])e(` ${Y.instanceId}: ${Y.output?.trim()||Y.status}`);if(!z.success)r(`Restore failed: ${z.error||"unknown error"}`),process.exitCode=1}catch(k){r(`Restore failed: ${k.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(t)=>{i("Quick Deploy (push-to-deploy)");try{let m=await Ne(),{buildQuickDeployCi:k,inferQuickDeployProvider:I}=await import("./chunk-jx062xpq.js"),L=t?.provider?.toLowerCase();if(L&&!["github","gitlab","bitbucket"].includes(L))throw Error(`Unsupported CI provider '${t?.provider}'. Use github, gitlab, or bitbucket.`);let z=L;if(!z)try{let Z=dl("git remote get-url origin",{stdio:["ignore","pipe","ignore"]}).toString().trim();z=I(Z)}catch{}let Y=k(m,t?.env||"production",{provider:z,site:t?.site,skipDnsVerification:t?.skipDnsVerification,setup:In("pantry.lock")?"pantry":"bun",sshPrivateKeySecret:t?.sshKeySecret});if(!Y){a("Could not resolve a GitHub, GitLab, or Bitbucket provider from --provider, the origin remote, or a configured site repository."),process.exitCode=1;return}if(In(Y.path)&&!t?.force){a(`${Y.path} already exists — re-run with --force to overwrite.`);return}au(Qf(Y.path),{recursive:!0}),Zf(Y.path,Y.content),n(`Wrote ${Y.path} (${Y.provider}, deploys on push to '${Y.branch}').`),e("Next: commit it and add your provider credentials as CI secrets/variables.")}catch(m){r(`Quick deploy setup failed: ${m.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{setMaintenance:I}=await import("./chunk-6ybjfjbc.js");await I(m,k,!0,t?.secret)}catch(m){r(`Failed to enable maintenance mode: ${m.message}`),process.exitCode=1}}),R.command("up","Bring the serverless app out of maintenance mode").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",{setMaintenance:I}=await import("./chunk-6ybjfjbc.js");await I(m,k,!1)}catch(m){r(`Failed to disable maintenance mode: ${m.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{runAndRecordCommand:L}=await import("./chunk-6ybjfjbc.js"),{id:z,output:Y}=await L(k,I,t);if(e(Y),z>0)e(`
402
- (recorded as #${z} — re-run with \`cloud command:again ${z}\`)`)}catch(k){r(`Command failed: ${k.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{listCommandHistory:I}=await import("./chunk-6ybjfjbc.js"),L=await I(m,k);if(!L.length){e("No command history yet.");return}let z=Number(t?.limit??20);i(`Command history — ${m.project.slug} (${k})`),c(["#","When","Status","Command"],L.slice(-z).reverse().map((Y)=>[String(Y.id),Y.timestamp,Y.status,Y.command]))}catch(m){r(`Failed to read history: ${m.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{getCommandRecord:L,runAndRecordCommand:z}=await import("./chunk-6ybjfjbc.js"),Y=await L(k,I,t?Number(t):void 0);if(!Y){r(t?`No command #${t} in history.`:"No command history to re-run."),process.exitCode=1;return}e(`Re-running #${Y.id}: ${Y.command}`);let Z=await z(k,I,Y.command);if(e(Z.output),Z.id>0)e(`
403
- (recorded as #${Z.id})`)}catch(k){r(`Command failed: ${k.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{runDbQuery:L}=await import("./chunk-6ybjfjbc.js"),z=await L(k,I,t);e(z)}catch(k){r(`Query failed: ${k.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(t,m,k)=>{i("Scaling serverless database");try{let I=await Ne(),L=k?.env||"production",z=Number(t),Y=Number(m);if(!(z>0)||!(Y>=z)){r("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:Z}=await import("./chunk-6ybjfjbc.js");await Z(I,L,z,Y)}catch(I){r(`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(t)=>{i("Restoring serverless database");try{let m=await Ne(),k=t?.env||"production",I;if(t?.to){if(I=new Date(t.to),Number.isNaN(I.getTime())){r(`Invalid --to timestamp: ${t.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:L}=await import("./chunk-6ybjfjbc.js");await L(m,k,{toTime:I,latest:t?.latest,target:t?.target})}catch(m){r(`Restore failed: ${m.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{serverlessInfo:I}=await import("./chunk-6ybjfjbc.js"),L=await I(m,k);if(i(`${L.slug} (${L.environment})`),e(`Stack: ${L.stackStatus}`),e(`Region: ${L.region}`),L.endpoint)e(`URL: ${L.endpoint}`);if(L.assetUrl)e(`Assets: ${L.assetUrl}`);if(e(`Scheduler:${L.scheduler==="off"?" off":` ${L.scheduler}`}`),e(`Queues: ${L.queues.length?L.queues.join(", "):"none"}`),e(`Warming: ${L.provisionedConcurrency>0?`provisioned concurrency ×${L.provisionedConcurrency}`:"none / ping-warm"}`),L.lastRelease)e(`Release: ${L.lastRelease.sha.slice(0,12)} @ ${L.lastRelease.timestamp}`);c(["Function","Version","Provisioned"],L.functions.map((z)=>[z.name,z.version,z.provisioned?`${z.provisioned.status} ${z.provisioned.allocated}/${z.provisioned.requested}`:"—"]))}catch(m){r(`Failed to read info: ${m.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(t)=>{i("Building management dashboard (live data)");try{let{existsSync:m}=await import("node:fs"),k=t?.ui||"ui";if(!m(`${k}/package.json`)){r(`No UI project at ${k}/ (expected ${k}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let I=await Ne(),L=t?.env||"production";u("Gathering live data from AWS");let z=null;if(I.environments?.[L]?.app){let{resolveDashboardData:ne}=await import("./chunk-tpy9t3cv.js"),ie=await ne(I,L).catch((se)=>(a(`Serverless data unavailable (${se.message}) — that view uses sample data.`),null));if(ie)z={...z??{},...ie}}if(I.infrastructure?.compute){let{resolveServerDashboardData:ne}=await import("./chunk-abt0636a.js"),ie=await ne(I,L).catch(()=>null);if(ie){if(ie._serverReachable===!1)a("Server box not reachable over SSM — server view uses config + sample data.");z={...z??{},...ie}}}u("Building dashboard");let{encodeDashboardPayload:Y}=await import("./chunk-haezjam0.js"),{execSync:Z}=await import("node:child_process"),{rmSync:X}=await import("node:fs");for(let ne of[".stx/ssg-cache",".stx/cache"])X(`${k}/${ne}`,{recursive:!0,force:!0});Z("bun run build",{cwd:k,stdio:"inherit",env:{...process.env,...z?{TSCLOUD_DASHBOARD_DATA:Y(z)}:{}}}),n(`Dashboard built → ${k}/dist${z?" (live data)":" (sample data)"}`)}catch(m){r(`Dashboard build failed: ${m.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(t)=>{i("Building PHP runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.php||"8.3",z=`${t?.name||"tscloud-php"}-${L.replace(".","")}-${I}`,Y=t?.bucket||`${m?.project.slug||"tscloud"}-layers`,{buildPhpRuntimeLayerZip:Z}=await import("./chunk-7848wre2.js"),{S3Client:X}=await import("./chunk-1rrmswhq.js"),{LambdaClient:ne}=await import("./chunk-9zwvysdn.js"),ie=Z({architecture:I,phpVersion:L,onStep:(ke)=>u(ke)});e(`Layer: ${ie.fileCount} files, ${(ie.zip.length/1024/1024).toFixed(1)} MB`);let se=new X(k);if(!await se.bucketExists(Y))u(`Creating layer bucket ${Y}`),await se.createBucket(Y);let be=`layers/${z}.zip`;u("Uploading layer zip"),await se.putObject({bucket:Y,key:be,body:ie.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new ne(k).publishLayerVersion({LayerName:z,Description:`ts-cloud PHP ${L} runtime (${I})`,Content:{S3Bucket:Y,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["PHP runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'php', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_PHP_LAYER_ARN before deploying."].join(`
404
- `),"green")}catch(m){r(`Layer build failed: ${m.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(t)=>{i("Building Node runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.node||"24",{buildNodeRuntimeLayerZip:z}=await import("./chunk-7848wre2.js"),{S3Client:Y}=await import("./chunk-1rrmswhq.js"),{LambdaClient:Z}=await import("./chunk-9zwvysdn.js"),X=z({architecture:I,version:L,onStep:(ke)=>u(ke)}),ne=`${t?.name||"tscloud-node"}-${X.version.split(".")[0]}-${I}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Node ${X.version}, ${(X.zip.length/1024/1024).toFixed(1)} MB`);let se=new Y(k);if(!await se.bucketExists(ie))u(`Creating layer bucket ${ie}`),await se.createBucket(ie);let be=`layers/${ne}.zip`;u("Uploading layer zip"),await se.putObject({bucket:ie,key:be,body:X.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new Z(k).publishLayerVersion({LayerName:ne,Description:`ts-cloud Node ${X.version} runtime (${I})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["Node runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'node', runtimeVersion: '${X.version.split(".")[0]}', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_NODE_LAYER_ARN before deploying."].join(`
405
- `),"green")}catch(m){r(`Layer build failed: ${m.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(t)=>{i("Building Bun runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.bun||"latest",{buildBunRuntimeLayerZip:z}=await import("./chunk-7848wre2.js"),{S3Client:Y}=await import("./chunk-1rrmswhq.js"),{LambdaClient:Z}=await import("./chunk-9zwvysdn.js"),X=z({architecture:I,version:L,onStep:(ke)=>u(ke)}),ne=`${t?.name||"tscloud-bun"}-${X.version.replace(/\./g,"")}-${I}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Bun ${X.version}, ${(X.zip.length/1024/1024).toFixed(1)} MB`);let se=new Y(k);if(!await se.bucketExists(ie))u(`Creating layer bucket ${ie}`),await se.createBucket(ie);let be=`layers/${ne}.zip`;u("Uploading layer zip"),await se.putObject({bucket:ie,key:be,body:X.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new Z(k).publishLayerVersion({LayerName:ne,Description:`ts-cloud Bun ${X.version} runtime (${I})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["Bun runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'bun', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_BUN_LAYER_ARN before deploying."].join(`
400
+ `),{runComputeRecipe:Y}=await import("./chunk-4kt2sgqk.js"),Z=await Y({driver:O({config:I}),slug:I.project.slug,environment:L,logger:f},{name:t,script:z,user:k?.user});for(let X of Z.perInstance||[])e(`
401
+ ${X.instanceId}:`),e(X.output?.trimEnd()||"(no output)");if(!Z.success)process.exitCode=1}catch(I){r(`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(t,m)=>{i("Database Restore");try{let k=await Ne(),I=m?.env||"production",{restoreDatabaseBackup:L}=await import("./chunk-4kt2sgqk.js"),z=await L({driver:O({config:k}),slug:k.project.slug,environment:I,logger:f},{database:w(k),from:t});for(let Y of z.perInstance||[])e(` ${Y.instanceId}: ${Y.output?.trim()||Y.status}`);if(!z.success)r(`Restore failed: ${z.error||"unknown error"}`),process.exitCode=1}catch(k){r(`Restore failed: ${k.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(t)=>{i("Quick Deploy (push-to-deploy)");try{let m=await Ne(),{buildQuickDeployCi:k,inferQuickDeployProvider:I}=await import("./chunk-mhmvr5w3.js"),L=t?.provider?.toLowerCase();if(L&&!["github","gitlab","bitbucket"].includes(L))throw Error(`Unsupported CI provider '${t?.provider}'. Use github, gitlab, or bitbucket.`);let z=L;if(!z)try{let Z=dl("git remote get-url origin",{stdio:["ignore","pipe","ignore"]}).toString().trim();z=I(Z)}catch{}let Y=k(m,t?.env||"production",{provider:z,site:t?.site,skipDnsVerification:t?.skipDnsVerification,setup:In("pantry.lock")?"pantry":"bun",sshPrivateKeySecret:t?.sshKeySecret});if(!Y){a("Could not resolve a GitHub, GitLab, or Bitbucket provider from --provider, the origin remote, or a configured site repository."),process.exitCode=1;return}if(In(Y.path)&&!t?.force){a(`${Y.path} already exists — re-run with --force to overwrite.`);return}au(Qf(Y.path),{recursive:!0}),Zf(Y.path,Y.content),n(`Wrote ${Y.path} (${Y.provider}, deploys on push to '${Y.branch}').`),e("Next: commit it and add your provider credentials as CI secrets/variables.")}catch(m){r(`Quick deploy setup failed: ${m.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{setMaintenance:I}=await import("./chunk-8dzqjsz1.js");await I(m,k,!0,t?.secret)}catch(m){r(`Failed to enable maintenance mode: ${m.message}`),process.exitCode=1}}),R.command("up","Bring the serverless app out of maintenance mode").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await Ne(),k=t?.env||"production",{setMaintenance:I}=await import("./chunk-8dzqjsz1.js");await I(m,k,!1)}catch(m){r(`Failed to disable maintenance mode: ${m.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{runAndRecordCommand:L}=await import("./chunk-8dzqjsz1.js"),{id:z,output:Y}=await L(k,I,t);if(e(Y),z>0)e(`
402
+ (recorded as #${z} — re-run with \`cloud command:again ${z}\`)`)}catch(k){r(`Command failed: ${k.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{listCommandHistory:I}=await import("./chunk-8dzqjsz1.js"),L=await I(m,k);if(!L.length){e("No command history yet.");return}let z=Number(t?.limit??20);i(`Command history — ${m.project.slug} (${k})`),c(["#","When","Status","Command"],L.slice(-z).reverse().map((Y)=>[String(Y.id),Y.timestamp,Y.status,Y.command]))}catch(m){r(`Failed to read history: ${m.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{getCommandRecord:L,runAndRecordCommand:z}=await import("./chunk-8dzqjsz1.js"),Y=await L(k,I,t?Number(t):void 0);if(!Y){r(t?`No command #${t} in history.`:"No command history to re-run."),process.exitCode=1;return}e(`Re-running #${Y.id}: ${Y.command}`);let Z=await z(k,I,Y.command);if(e(Z.output),Z.id>0)e(`
403
+ (recorded as #${Z.id})`)}catch(k){r(`Command failed: ${k.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(t,m)=>{try{let k=await Ne(),I=m?.env||"production",{runDbQuery:L}=await import("./chunk-8dzqjsz1.js"),z=await L(k,I,t);e(z)}catch(k){r(`Query failed: ${k.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(t,m,k)=>{i("Scaling serverless database");try{let I=await Ne(),L=k?.env||"production",z=Number(t),Y=Number(m);if(!(z>0)||!(Y>=z)){r("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:Z}=await import("./chunk-8dzqjsz1.js");await Z(I,L,z,Y)}catch(I){r(`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(t)=>{i("Restoring serverless database");try{let m=await Ne(),k=t?.env||"production",I;if(t?.to){if(I=new Date(t.to),Number.isNaN(I.getTime())){r(`Invalid --to timestamp: ${t.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:L}=await import("./chunk-8dzqjsz1.js");await L(m,k,{toTime:I,latest:t?.latest,target:t?.target})}catch(m){r(`Restore failed: ${m.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(t)=>{try{let m=await Ne(),k=t?.env||"production",{serverlessInfo:I}=await import("./chunk-8dzqjsz1.js"),L=await I(m,k);if(i(`${L.slug} (${L.environment})`),e(`Stack: ${L.stackStatus}`),e(`Region: ${L.region}`),L.endpoint)e(`URL: ${L.endpoint}`);if(L.assetUrl)e(`Assets: ${L.assetUrl}`);if(e(`Scheduler:${L.scheduler==="off"?" off":` ${L.scheduler}`}`),e(`Queues: ${L.queues.length?L.queues.join(", "):"none"}`),e(`Warming: ${L.provisionedConcurrency>0?`provisioned concurrency ×${L.provisionedConcurrency}`:"none / ping-warm"}`),L.lastRelease)e(`Release: ${L.lastRelease.sha.slice(0,12)} @ ${L.lastRelease.timestamp}`);c(["Function","Version","Provisioned"],L.functions.map((z)=>[z.name,z.version,z.provisioned?`${z.provisioned.status} ${z.provisioned.allocated}/${z.provisioned.requested}`:"—"]))}catch(m){r(`Failed to read info: ${m.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(t)=>{i("Building management dashboard (live data)");try{let{existsSync:m}=await import("node:fs"),k=t?.ui||"ui";if(!m(`${k}/package.json`)){r(`No UI project at ${k}/ (expected ${k}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let I=await Ne(),L=t?.env||"production";u("Gathering live data from AWS");let z=null;if(I.environments?.[L]?.app){let{resolveDashboardData:ne}=await import("./chunk-q82s4yzg.js"),ie=await ne(I,L).catch((se)=>(a(`Serverless data unavailable (${se.message}) — that view uses sample data.`),null));if(ie)z={...z??{},...ie}}if(I.infrastructure?.compute){let{resolveServerDashboardData:ne}=await import("./chunk-1gzxerk9.js"),ie=await ne(I,L).catch(()=>null);if(ie){if(ie._serverReachable===!1)a("Server box not reachable over SSM — server view uses config + sample data.");z={...z??{},...ie}}}u("Building dashboard");let{encodeDashboardPayload:Y}=await import("./chunk-haezjam0.js"),{execSync:Z}=await import("node:child_process"),{rmSync:X}=await import("node:fs");for(let ne of[".stx/ssg-cache",".stx/cache"])X(`${k}/${ne}`,{recursive:!0,force:!0});Z("bun run build",{cwd:k,stdio:"inherit",env:{...process.env,...z?{TSCLOUD_DASHBOARD_DATA:Y(z)}:{}}}),n(`Dashboard built → ${k}/dist${z?" (live data)":" (sample data)"}`)}catch(m){r(`Dashboard build failed: ${m.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(t)=>{i("Building PHP runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.php||"8.3",z=`${t?.name||"tscloud-php"}-${L.replace(".","")}-${I}`,Y=t?.bucket||`${m?.project.slug||"tscloud"}-layers`,{buildPhpRuntimeLayerZip:Z}=await import("./chunk-vr9jcw65.js"),{S3Client:X}=await import("./chunk-1rrmswhq.js"),{LambdaClient:ne}=await import("./chunk-9zwvysdn.js"),ie=Z({architecture:I,phpVersion:L,onStep:(ke)=>u(ke)});e(`Layer: ${ie.fileCount} files, ${(ie.zip.length/1024/1024).toFixed(1)} MB`);let se=new X(k);if(!await se.bucketExists(Y))u(`Creating layer bucket ${Y}`),await se.createBucket(Y);let be=`layers/${z}.zip`;u("Uploading layer zip"),await se.putObject({bucket:Y,key:be,body:ie.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new ne(k).publishLayerVersion({LayerName:z,Description:`ts-cloud PHP ${L} runtime (${I})`,Content:{S3Bucket:Y,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["PHP runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'php', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_PHP_LAYER_ARN before deploying."].join(`
404
+ `),"green")}catch(m){r(`Layer build failed: ${m.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(t)=>{i("Building Node runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.node||"24",{buildNodeRuntimeLayerZip:z}=await import("./chunk-vr9jcw65.js"),{S3Client:Y}=await import("./chunk-1rrmswhq.js"),{LambdaClient:Z}=await import("./chunk-9zwvysdn.js"),X=z({architecture:I,version:L,onStep:(ke)=>u(ke)}),ne=`${t?.name||"tscloud-node"}-${X.version.split(".")[0]}-${I}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Node ${X.version}, ${(X.zip.length/1024/1024).toFixed(1)} MB`);let se=new Y(k);if(!await se.bucketExists(ie))u(`Creating layer bucket ${ie}`),await se.createBucket(ie);let be=`layers/${ne}.zip`;u("Uploading layer zip"),await se.putObject({bucket:ie,key:be,body:X.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new Z(k).publishLayerVersion({LayerName:ne,Description:`ts-cloud Node ${X.version} runtime (${I})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["Node runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'node', runtimeVersion: '${X.version.split(".")[0]}', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_NODE_LAYER_ARN before deploying."].join(`
405
+ `),"green")}catch(m){r(`Layer build failed: ${m.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(t)=>{i("Building Bun runtime layer");try{let m=await Ne().catch(()=>null),k=t?.region||m?.project.region||"us-east-1",I=t?.arch||"x86_64",L=t?.bun||"latest",{buildBunRuntimeLayerZip:z}=await import("./chunk-vr9jcw65.js"),{S3Client:Y}=await import("./chunk-1rrmswhq.js"),{LambdaClient:Z}=await import("./chunk-9zwvysdn.js"),X=z({architecture:I,version:L,onStep:(ke)=>u(ke)}),ne=`${t?.name||"tscloud-bun"}-${X.version.replace(/\./g,"")}-${I}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Bun ${X.version}, ${(X.zip.length/1024/1024).toFixed(1)} MB`);let se=new Y(k);if(!await se.bucketExists(ie))u(`Creating layer bucket ${ie}`),await se.createBucket(ie);let be=`layers/${ne}.zip`;u("Uploading layer zip"),await se.putObject({bucket:ie,key:be,body:X.zip,contentType:"application/zip"}),u("Publishing layer version");let le=await new Z(k).publishLayerVersion({LayerName:ne,Description:`ts-cloud Bun ${X.version} runtime (${I})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[I]});Ee(["Bun runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'bun', layers: ['${le.LayerVersionArn}'] }`,"or set TSCLOUD_BUN_LAYER_ARN before deploying."].join(`
406
406
  `),"green")}catch(m){r(`Layer build failed: ${m.message}`),process.exitCode=1}}),R.command("deploy:status","Check deployment status").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(t)=>{i("Deployment Status");try{let m=await Ne(),k=t?.env||"production",I=t?.stack||T(m,k),L=m.project.region||"us-east-1";e(`Stack: ${I}`),e(`Region: ${L}`);let z=new s("Checking deployment status...");z.start();let Z=await new v(L).describeStacks({stackName:I});if(Z.Stacks.length===0){z.fail("Stack not found"),_r("No deployment found for this environment");return}let X=Z.Stacks[0];if(z.succeed("Status retrieved"),e(`
407
407
  Status: ${X.StackStatus}`),e(`Created: ${X.CreationTime}`),X.LastUpdatedTime)e(`Last Updated: ${X.LastUpdatedTime}`);if(X.Outputs&&X.Outputs.length>0){e(`
408
408
  Outputs:`);for(let ne of X.Outputs)e(` ${ne.OutputKey}: ${ne.OutputValue}`)}}catch(m){r(`Failed to get status: ${m.message}`)}}),R.command("deploy:rollback","Rollback to previous version").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(t)=>{i("Rolling Back Deployment");try{let m=await Ne(),k=t?.env||"production",I=t?.stack||T(m,k),L=m.project.region||"us-east-1";if(e(`Stack: ${I}`),e(`Region: ${L}`),!await d(`