@stacksjs/ts-cloud 0.16.50 → 0.16.51

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-cw3rhg1c.js → chunk-20dp8658.js} +1 -1
  2. package/dist/bin/{chunk-k9f94hg4.js → chunk-45thdtvf.js} +165 -165
  3. package/dist/bin/{chunk-7cs9nnjy.js → chunk-5c4xh61a.js} +1 -1
  4. package/dist/bin/chunk-67vf8myy.js +1 -0
  5. package/dist/bin/{chunk-e6ewfmbp.js → chunk-83brtkvn.js} +1 -1
  6. package/dist/bin/chunk-87g6jcfm.js +1 -0
  7. package/dist/bin/{chunk-11y7yang.js → chunk-93yw46n7.js} +1 -1
  8. package/dist/bin/{chunk-qsfhb3x7.js → chunk-9qdrv6zp.js} +1 -1
  9. package/dist/bin/{chunk-j2wkxp7d.js → chunk-a7hhzbvm.js} +1 -1
  10. package/dist/bin/{chunk-hdqxyxs0.js → chunk-cjagqdk3.js} +5 -5
  11. package/dist/bin/{chunk-mdkd46c5.js → chunk-d24ztt54.js} +1 -1
  12. package/dist/bin/{chunk-f2t67d76.js → chunk-ddyd6f14.js} +1 -1
  13. package/dist/bin/{chunk-y12vn1h1.js → chunk-f0vedy45.js} +1 -1
  14. package/dist/bin/{chunk-w89fyres.js → chunk-f578z20t.js} +1 -1
  15. package/dist/bin/{chunk-e7pce8jb.js → chunk-f78wmcvb.js} +1 -1
  16. package/dist/bin/{chunk-vavwhhrp.js → chunk-fhe0mdjg.js} +1 -1
  17. package/dist/bin/chunk-g6ph425d.js +1 -0
  18. package/dist/bin/{chunk-7jj0g6jk.js → chunk-gc199s7a.js} +4 -4
  19. package/dist/bin/chunk-m5jvp6ph.js +1 -0
  20. package/dist/bin/{chunk-9ehb4hc6.js → chunk-n5kdne4p.js} +1 -1
  21. package/dist/bin/{chunk-tcj1z34y.js → chunk-ngmewar1.js} +1 -1
  22. package/dist/bin/{chunk-xaqkj8fn.js → chunk-p6wxv8yq.js} +1 -1
  23. package/dist/bin/{chunk-f4mpkpbf.js → chunk-vpt43nwa.js} +1 -1
  24. package/dist/bin/{chunk-kmpvqby6.js → chunk-wv8060cw.js} +1 -1
  25. package/dist/bin/{chunk-r524t8v8.js → chunk-zywk12mp.js} +1 -1
  26. package/dist/bin/cli.js +16 -16
  27. package/dist/bin/dashboard-server.js +1 -1
  28. package/dist/chunk-2gqm2h84.js +1 -0
  29. package/dist/{chunk-5hgcr7r2.js → chunk-53kyxata.js} +2 -2
  30. package/dist/{chunk-zbx9yehq.js → chunk-6gnmrtp9.js} +1 -1
  31. package/dist/{chunk-85fyadq0.js → chunk-dw0cvqdr.js} +13 -13
  32. package/dist/{chunk-a8hs75xd.js → chunk-p101nhg2.js} +1 -1
  33. package/dist/{chunk-18h7na1g.js → chunk-prtvb2fh.js} +27 -27
  34. package/dist/{chunk-cpba1hz2.js → chunk-pz33w7gv.js} +1 -1
  35. package/dist/{chunk-nnnhq6sx.js → chunk-qcv4twc6.js} +1 -1
  36. package/dist/{chunk-nmnf1ha6.js → chunk-x4qye2rc.js} +1 -1
  37. package/dist/{chunk-fqgvackc.js → chunk-xgc6hskd.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 +2 -2
  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 +6 -6
  53. package/dist/ui/data/services.html +5 -5
  54. package/dist/ui/data/volumes.html +5 -5
  55. package/dist/ui/index.html +6 -6
  56. package/dist/ui/infrastructure/topology.html +5 -5
  57. package/dist/ui/integrations.html +1 -1
  58. package/dist/ui/operations/alerts.html +5 -5
  59. package/dist/ui/operations/configuration.html +6 -6
  60. package/dist/ui/operations/jobs.html +6 -6
  61. package/dist/ui/operations/maintenance.html +6 -6
  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 +6 -6
  65. package/dist/ui/operations/regions.html +6 -6
  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 +6 -6
  69. package/dist/ui/security.html +1 -1
  70. package/dist/ui/server/actions.html +6 -6
  71. package/dist/ui/server/activity.html +2 -2
  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 +5 -5
  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 +5 -5
  78. package/dist/ui/server/logs.html +5 -5
  79. package/dist/ui/server/metrics.html +5 -5
  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 +5 -5
  98. package/dist/ui/serverless.html +5 -5
  99. package/package.json +3 -3
  100. package/dist/bin/chunk-512ecg6y.js +0 -1
  101. package/dist/bin/chunk-7ewbxsan.js +0 -1
  102. package/dist/bin/chunk-q9awn1n3.js +0 -1
  103. package/dist/bin/chunk-v2qk9jeb.js +0 -1
  104. package/dist/chunk-r4kedmas.js +0 -1
package/dist/bin/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import{C,zt,n,r,a,Pr,e,d,i,s,R,u,No,c,mn,Ee,Bs,js,Vs,zs,f}from"./chunk-t970yjvz.js";import{la,H,Mr,w,B,zo,l,o,T,ua,pa,ma,Oe,Ve,nt,qo,Cn,Oi,Tn,Go,ya,ba,Sa,va,Ta,j,b,L,it,k,ye,Ko,He,Wt,$i,Ie,Jo,Li,Kt,It,Ea,wa}from"./chunk-k9f94hg4.js";import"./chunk-33ntxz01.js";import{Le,x,Nn,y,xn,Gi,_n,ns,zr,st,xe,On,$n,Ln,Mn,Un,Bn,jn,Vn,oe,tr,rr,zn,Hr,Hn,qn,Gn,Wn,Kn,Jn,Xn,Qn,at,nr,ir,Nt,qr,or,sr,Wi,xt,Yn,de,Zn,ei,ti,Gr,Wr,ri,Kr,ar,cr,ct,_t,Ot,Jr,ue,ni,lc,dc,lr,uc,q,Ki,qe,lt,dt,ii,Xr,oi,Qr,si,ai,Yr,is,pe,ve,Me,Ce,ci,dr}from"./chunk-7jj0g6jk.js";import{p,ia}from"./chunk-z06jkvvr.js";import{ce,h,Lr}from"./chunk-kmpvqby6.js";import{Nr,wt,xr,_r,Or,$r,yn}from"./chunk-tcj1z34y.js";import{S,Lt,fi,bs,br,Sc,vc,Cc,hi,yi,an,Mt,cn,ft,ht,Qe,Fe,Ye,yt,Sr,Be,Ze,bi,Si,et,ln,dn,co,uo,Tr,Ut,bt,Ft,ee,fo,Ti,Ei,ks}from"./chunk-7cs9nnjy.js";import{tt,Bt,wr,_s,Os,Ar,he,wi,Rr,So,vo,Co,To,Eo,wo,W,jt,M,Ai}from"./chunk-7czb1kgg.js";import{J,I,xo,Ws,Ks,Hc,qc,Pi,Tt,Di}from"./chunk-hdqxyxs0.js";import{v}from"./chunk-hhmqsrfc.js";import{Q}from"./chunk-te52z1wk.js";import{Et,g}from"./chunk-dv2he3vc.js";import{We,os,me,Ji,di,Xi,Qi,Zr,Yi,Zi,Te,Z,Ke,_e,en,ur,Je,pr,tn,pt,ge,mt,gr,fr,hr,rn,yr,O,to,ro,ui,ss,nn,as,cs,gc,no,ls,ds,us,ps,gt,ms,io,oo}from"./chunk-mdkd46c5.js";import"./chunk-9ehb4hc6.js";import{P}from"./chunk-5ny7rggt.js";import{fe}from"./chunk-0wtshht7.js";import{K,vt,Do}from"./chunk-j2wkxp7d.js";import{se,G,pc,mc,Ge}from"./chunk-f2t67d76.js";import{Zt,Dn,er,Hi,kn,rs}from"./chunk-734n0gkw.js";import"./chunk-e7pce8jb.js";import{E}from"./chunk-da6dmacg.js";import{ut}from"./chunk-we2raqk3.js";import{te,we}from"./chunk-q2rqmc2x.js";import{V}from"./chunk-yfa84s0c.js";import"./chunk-gr1ra9nj.js";import{qi}from"./chunk-sa9c8vb5.js";import"./chunk-11y7yang.js";import"./chunk-y12vn1h1.js";import{gi}from"./chunk-m3xap663.js";import{Er}from"./chunk-mcg4wg4j.js";import{St}from"./chunk-ppd463ev.js";import{F}from"./chunk-rwbdtxte.js";import{N}from"./chunk-811k54jq.js";import{existsSync as Lu}from"node:fs";import xa from"node:fs/promises";import zl from"node:os";import Na from"node:path";import ao from"node:process";import{EventEmitter as Fu}from"node:events";import ji from"node:process";import Ul from"node:process";import Fa from"node:process";import Ls from"node:process";import Ho from"node:process";import Gl from"node:tty";import km,{stdin as Xh,stdout as ey}from"node:process";class Hl{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let D=zl.homedir(),t=Na.join(D,".config","clapp");this.configPath=Na.join(t,"telemetry.json")}async isEnabled(){if(ao.env.DO_NOT_TRACK==="1"||ao.env.DO_NOT_TRACK==="true")return!1;if(ao.env.NO_TELEMETRY==="1"||ao.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let D=await this.loadConfig();if(D.enabled=!0,!D.userId)D.userId=this.generateUserId();await this.saveConfig(D)}async disable(){let D=await this.loadConfig();D.enabled=!1,await this.saveConfig(D)}async track(D,t){if(!await this.isEnabled())return;let A={event:D,...t,timestamp:Date.now(),platform:zl.platform(),nodeVersion:ao.version};if(this.events.push(A),this.events.length>=10)await this.send()}async trackCommand(D,t){await this.track("command",{command:D,duration:t})}async trackError(D,t){await this.track("error",{error:D,command:t})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let t=await this.loadConfig();return t.lastSent=Date.now(),await this.saveConfig(t),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let t=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(t),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(D){return new Promise((t)=>setTimeout(t,D))}async status(){let D=await this.loadConfig();return{enabled:D.enabled,doNotTrack:ao.env.DO_NOT_TRACK==="1"||ao.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:D.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(Lu(this.configPath)){let D=await xa.readFile(this.configPath,"utf-8");return this.config=JSON.parse(D),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig(D){this.config=D;try{let t=Na.dirname(this.configPath);await xa.mkdir(t,{recursive:!0}),await xa.writeFile(this.configPath,JSON.stringify(D,null,2),"utf-8")}catch{}}generateUserId(){let D=Math.random().toString(36).substring(2,15),t=Date.now().toString(36);return`${D}-${t}`}}var Mh=new Hl;function La(D){return D.replace(/[<[].+/,"").trim()}function ju(D){let t=/<([^>]+)>/g,m=/\[([^\]]+)\]/g,A=[],_=(Y)=>{let X=!1,ne=Y[1];if(ne.startsWith("..."))ne=ne.slice(3),X=!0;return{required:Y[0].startsWith("<"),value:ne,variadic:X}},z;while(z=t.exec(D))A.push(_(z));let U;while(U=m.exec(D))A.push(_(U));return A}function Bu(D){let t={alias:{},boolean:[]};for(let[m,A]of D.entries()){if(A.names.length>1)t.alias[A.names[0]]=A.names.slice(1);if(A.isBoolean)if(A.negated){if(!D.some((z,U)=>U!==m&&z.names.some((Y)=>A.names.includes(Y))&&typeof z.required==="boolean"))t.boolean.push(A.names[0])}else t.boolean.push(A.names[0])}return t}function Wl(D){return D.reduce((t,m)=>t.length>=m.length?t:m,"")}function Oa(D,t){return D.length>=t?D:`${D}${" ".repeat(t-D.length)}`}function Ns(D){return D.replace(/([a-z])-([a-z])/g,(t,m,A)=>m+A.toUpperCase())}function _u(D,t,m){let A=0,_=t.length,z=D,U;for(;A<_;++A)U=z[t[A]],z=z[t[A]]=A===_-1?m:U!=null?U:!!~t[A+1].indexOf(".")||!(+t[A+1]>-1)?{}:[]}function Mu(D,t){for(let m of Object.keys(t)){let A=t[m];if(A.shouldTransform){if(D[m]=Array.prototype.concat.call([],D[m]),typeof A.transformFunction==="function")D[m]=D[m].map(A.transformFunction)}}}function zu(D){let t=/([^\\/]+)$/.exec(D);return t?t[1]:""}function Yo(D){return D.split(".").map((t,m)=>m===0?Ns(t):t).join(".")}class Zo extends Error{exitCode=2;isUsageError=!0;usage;constructor(D,t){super(D);if(this.name=this.constructor.name,t!==void 0)this.usage=t;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(D).stack}format(D=!1){if(D&&this.stack)return`${this.message}
2
+ import{C,zt,n,r,a,Pr,e,d,i,s,R,u,No,c,mn,Ee,Bs,js,Vs,zs,f}from"./chunk-t970yjvz.js";import{la,H,Mr,w,B,zo,l,o,T,ua,pa,ma,Oe,Ve,nt,qo,Cn,Oi,Tn,Go,ya,ba,Sa,va,Ta,j,b,L,it,k,ye,Ko,He,Wt,$i,Ie,Jo,Li,Kt,It,Ea,wa}from"./chunk-45thdtvf.js";import"./chunk-33ntxz01.js";import{Le,x,Nn,y,xn,Gi,_n,ns,zr,st,xe,On,$n,Ln,Mn,Un,Bn,jn,Vn,oe,tr,rr,zn,Hr,Hn,qn,Gn,Wn,Kn,Jn,Xn,Qn,at,nr,ir,Nt,qr,or,sr,Wi,xt,Yn,de,Zn,ei,ti,Gr,Wr,ri,Kr,ar,cr,ct,_t,Ot,Jr,ue,ni,lc,dc,lr,uc,q,Ki,qe,lt,dt,ii,Xr,oi,Qr,si,ai,Yr,is,pe,ve,Me,Ce,ci,dr}from"./chunk-gc199s7a.js";import{p,ia}from"./chunk-z06jkvvr.js";import{ce,h,Lr}from"./chunk-wv8060cw.js";import{Nr,wt,xr,_r,Or,$r,yn}from"./chunk-ngmewar1.js";import{S,Lt,fi,bs,br,Sc,vc,Cc,hi,yi,an,Mt,cn,ft,ht,Qe,Fe,Ye,yt,Sr,Be,Ze,bi,Si,et,ln,dn,co,uo,Tr,Ut,bt,Ft,ee,fo,Ti,Ei,ks}from"./chunk-5c4xh61a.js";import{tt,Bt,wr,_s,Os,Ar,he,wi,Rr,So,vo,Co,To,Eo,wo,W,jt,M,Ai}from"./chunk-7czb1kgg.js";import{J,I,xo,Ws,Ks,Hc,qc,Pi,Tt,Di}from"./chunk-cjagqdk3.js";import{v}from"./chunk-hhmqsrfc.js";import{Q}from"./chunk-te52z1wk.js";import{Et,g}from"./chunk-dv2he3vc.js";import{We,os,me,Ji,di,Xi,Qi,Zr,Yi,Zi,Te,Z,Ke,_e,en,ur,Je,pr,tn,pt,ge,mt,gr,fr,hr,rn,yr,O,to,ro,ui,ss,nn,as,cs,gc,no,ls,ds,us,ps,gt,ms,io,oo}from"./chunk-d24ztt54.js";import"./chunk-n5kdne4p.js";import{P}from"./chunk-5ny7rggt.js";import{fe}from"./chunk-0wtshht7.js";import{K,vt,Do}from"./chunk-a7hhzbvm.js";import{se,G,pc,mc,Ge}from"./chunk-ddyd6f14.js";import{Zt,Dn,er,Hi,kn,rs}from"./chunk-734n0gkw.js";import"./chunk-f78wmcvb.js";import{E}from"./chunk-da6dmacg.js";import{ut}from"./chunk-we2raqk3.js";import{te,we}from"./chunk-q2rqmc2x.js";import{V}from"./chunk-yfa84s0c.js";import"./chunk-gr1ra9nj.js";import{qi}from"./chunk-sa9c8vb5.js";import"./chunk-93yw46n7.js";import"./chunk-f0vedy45.js";import{gi}from"./chunk-m3xap663.js";import{Er}from"./chunk-mcg4wg4j.js";import{St}from"./chunk-ppd463ev.js";import{F}from"./chunk-rwbdtxte.js";import{N}from"./chunk-811k54jq.js";import{existsSync as Lu}from"node:fs";import xa from"node:fs/promises";import zl from"node:os";import Na from"node:path";import ao from"node:process";import{EventEmitter as Fu}from"node:events";import ji from"node:process";import Ul from"node:process";import Fa from"node:process";import Ls from"node:process";import Ho from"node:process";import Gl from"node:tty";import km,{stdin as Xh,stdout as ey}from"node:process";class Hl{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let D=zl.homedir(),t=Na.join(D,".config","clapp");this.configPath=Na.join(t,"telemetry.json")}async isEnabled(){if(ao.env.DO_NOT_TRACK==="1"||ao.env.DO_NOT_TRACK==="true")return!1;if(ao.env.NO_TELEMETRY==="1"||ao.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let D=await this.loadConfig();if(D.enabled=!0,!D.userId)D.userId=this.generateUserId();await this.saveConfig(D)}async disable(){let D=await this.loadConfig();D.enabled=!1,await this.saveConfig(D)}async track(D,t){if(!await this.isEnabled())return;let A={event:D,...t,timestamp:Date.now(),platform:zl.platform(),nodeVersion:ao.version};if(this.events.push(A),this.events.length>=10)await this.send()}async trackCommand(D,t){await this.track("command",{command:D,duration:t})}async trackError(D,t){await this.track("error",{error:D,command:t})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let t=await this.loadConfig();return t.lastSent=Date.now(),await this.saveConfig(t),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let t=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(t),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(D){return new Promise((t)=>setTimeout(t,D))}async status(){let D=await this.loadConfig();return{enabled:D.enabled,doNotTrack:ao.env.DO_NOT_TRACK==="1"||ao.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:D.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(Lu(this.configPath)){let D=await xa.readFile(this.configPath,"utf-8");return this.config=JSON.parse(D),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig(D){this.config=D;try{let t=Na.dirname(this.configPath);await xa.mkdir(t,{recursive:!0}),await xa.writeFile(this.configPath,JSON.stringify(D,null,2),"utf-8")}catch{}}generateUserId(){let D=Math.random().toString(36).substring(2,15),t=Date.now().toString(36);return`${D}-${t}`}}var Mh=new Hl;function La(D){return D.replace(/[<[].+/,"").trim()}function ju(D){let t=/<([^>]+)>/g,m=/\[([^\]]+)\]/g,A=[],_=(Y)=>{let X=!1,ne=Y[1];if(ne.startsWith("..."))ne=ne.slice(3),X=!0;return{required:Y[0].startsWith("<"),value:ne,variadic:X}},z;while(z=t.exec(D))A.push(_(z));let U;while(U=m.exec(D))A.push(_(U));return A}function Bu(D){let t={alias:{},boolean:[]};for(let[m,A]of D.entries()){if(A.names.length>1)t.alias[A.names[0]]=A.names.slice(1);if(A.isBoolean)if(A.negated){if(!D.some((z,U)=>U!==m&&z.names.some((Y)=>A.names.includes(Y))&&typeof z.required==="boolean"))t.boolean.push(A.names[0])}else t.boolean.push(A.names[0])}return t}function Wl(D){return D.reduce((t,m)=>t.length>=m.length?t:m,"")}function Oa(D,t){return D.length>=t?D:`${D}${" ".repeat(t-D.length)}`}function Ns(D){return D.replace(/([a-z])-([a-z])/g,(t,m,A)=>m+A.toUpperCase())}function _u(D,t,m){let A=0,_=t.length,z=D,U;for(;A<_;++A)U=z[t[A]],z=z[t[A]]=A===_-1?m:U!=null?U:!!~t[A+1].indexOf(".")||!(+t[A+1]>-1)?{}:[]}function Mu(D,t){for(let m of Object.keys(t)){let A=t[m];if(A.shouldTransform){if(D[m]=Array.prototype.concat.call([],D[m]),typeof A.transformFunction==="function")D[m]=D[m].map(A.transformFunction)}}}function zu(D){let t=/([^\\/]+)$/.exec(D);return t?t[1]:""}function Yo(D){return D.split(".").map((t,m)=>m===0?Ns(t):t).join(".")}class Zo extends Error{exitCode=2;isUsageError=!0;usage;constructor(D,t){super(D);if(this.name=this.constructor.name,t!==void 0)this.usage=t;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(D).stack}format(D=!1){if(D&&this.stack)return`${this.message}
3
3
 
4
4
  Stack trace:
5
5
  ${this.stack}`;return this.message}}function Uu(D){if(D instanceof Zo)return!0;return!!D&&typeof D==="object"&&D.name==="ClappError"&&typeof D.message==="string"}function Wu(){let{env:D}=Ul,{TERM:t,TERM_PROGRAM:m}=D;if(Ul.platform!=="win32")return t!=="linux";return Boolean(D.WT_SESSION)||Boolean(D.TERMINUS_SUBLIME)||D.ConEmuTask==="{cmd::Cmder}"||m==="Terminus-Sublime"||m==="vscode"||t==="xterm-256color"||t==="alacritty"||t==="rxvt-unicode"||t==="rxvt-unicode-256color"||D.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var Fs="\x1B",on=`${Fs}[`;var Vl={to(D,t){if(!t)return`${on}${D+1}G`;return`${on}${t+1};${D+1}H`},move(D,t){let m="";if(D<0)m+=`${on}${-D}D`;else if(D>0)m+=`${on}${D}C`;if(t<0)m+=`${on}${-t}A`;else if(t>0)m+=`${on}${t}B`;return m},up:(D=1)=>`${on}${D}A`,down:(D=1)=>`${on}${D}B`,forward:(D=1)=>`${on}${D}C`,backward:(D=1)=>`${on}${D}D`,nextLine:(D=1)=>`${on}E`.repeat(D),prevLine:(D=1)=>`${on}F`.repeat(D),left:`${on}G`,hide:`${on}?25l`,show:`${on}?25h`,save:`${Fs}7`,restore:`${Fs}8`};var Vh={screen:`${on}2J`,up:(D=1)=>`${on}1J`.repeat(D),down:(D=1)=>`${on}J`.repeat(D),line:`${on}2K`,lineEnd:`${on}K`,lineStart:`${on}1K`,lines(D){let t="";for(let m=0;m<D;m++)t+=this.line+(m<D-1?Vl.up():"");if(D)t+=Vl.left;return t}},qh={screen:`${Fs}c`};function Vu(D,t){let m=[];for(let A=0;A<=t.length;A++)m[A]=[A];for(let A=0;A<=D.length;A++)m[0][A]=A;for(let A=1;A<=t.length;A++)for(let _=1;_<=D.length;_++)if(t.charAt(A-1)===D.charAt(_-1))m[A][_]=m[A-1][_-1];else m[A][_]=Math.min(m[A-1][_-1]+1,m[A][_-1]+1,m[A-1][_]+1);return m[t.length][D.length]}function Kl(D,t,m=2,A=3){return t.map((_)=>({cmd:_,distance:Vu(D,_)})).filter(({distance:_})=>_<=m).sort((_,z)=>_.distance-z.distance).slice(0,A).map(({cmd:_})=>_)}function qu(D,t={}){let m={_:[]},A=t.alias||{},_=new Set(t.boolean||[]),z={};for(let X of Object.keys(A))for(let ne of A[X])z[ne]=X;for(let X of _)if(A[X])for(let ne of A[X])_.add(ne);function U(X,ne){if(X===void 0)return ne;if(typeof ne==="boolean")return ne;return Array.isArray(X)?[...X,ne]:[X,ne]}function Y(X,ne){let re=z[X]||X,ie=U(m[re],ne);if(m[re]=ie,A[re])for(let ae of A[re])m[ae]=ie;if(z[X]&&A[z[X]])for(let ae of A[z[X]])m[ae]=ie;m[X]=ie}for(let X=0;X<D.length;X++){let ne=D[X];if(ne==="--"){m._.push(...D.slice(X+1));break}if(ne.startsWith("--")){let re=ne.indexOf("=");if(re!==-1){let ie=Ns(ne.slice(2,re)),ae=ne.slice(re+1);Y(ie,ae)}else{let ie=ne.slice(2);if(ie.startsWith("no-")){let ke=Ns(ie.slice(3));Y(ke,!1);continue}let ae=Ns(ie),be=z[ae]||ae;if(_.has(be)||_.has(ae))Y(ae,!0);else{let ke=D[X+1];if(ke!==void 0&&!ke.startsWith("-"))Y(ae,ke),X++;else Y(ae,!0)}}}else if(ne.startsWith("-")&&ne.length>1){let re=ne.slice(1);for(let ie=0;ie<re.length;ie++){let ae=re[ie],be=z[ae]||ae;if(ie===re.length-1&&!_.has(be)&&!_.has(ae)){let ke=D[X+1];if(ke!==void 0&&!ke.startsWith("-"))Y(ae,ke),X++;else Y(ae,!0)}else Y(ae,!0)}}else m._.push(ne)}return m}class Jl{rawName;description;name;names;isBoolean;required;config;negated;constructor(D,t,m){if(this.rawName=D,this.description=t,this.config=Object.assign({},m),D=D.replace(/\.\*/g,""),this.negated=!1,this.names=La(D).split(",").map((A)=>{let _=A.trim().replace(/^-{1,2}/,"");if(_.startsWith("no-"))this.negated=!0,_=_.replace(/^no-/,"");return Yo(_)}).sort((A,_)=>A.length>_.length?1:-1),this.name=this.names[this.names.length-1],this.negated&&this.config.default==null)this.config.default=!0;if(D.includes("<"))this.required=!0;else if(D.includes("["))this.required=!1;else this.isBoolean=!0}}var Hh=Fa.argv,Gu=`${Fa.platform}-${Fa.arch} bun-v${typeof Bun<"u"?Bun.version:"unknown"}`,ql=Ls.argv,Hu=`${Ls.platform}-${Ls.arch} node-${Ls.version}`;class ja{rawName;description;config;cli;options;aliasNames;name;namespace;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;beforeHooks;afterHooks;middleware;constructor(D,t,m,A){this.rawName=D,this.description=t,this.config=m,this.cli=A,this.options=[],this.aliasNames=[],this.name=La(D);let _=La(D),z=_.indexOf(":");if(z>0)this.namespace=_.substring(0,z),this.name=_.substring(z+1);if(this.args=ju(D),this.examples=[],this.beforeHooks=[],this.afterHooks=[],this.middleware=[],!m)this.config={}}usage(D){return this.usageText=D,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(D,t="-v, --version"){return this.versionNumber=D,this.option(t,"Display version number"),this}example(D){return this.examples.push(D),this}option(D,t,m){let A=new Jl(D,t,m);return this.options.push(A),this}alias(D){return this.aliasNames.push(D),this}action(D){return this.commandAction=D,this}before(D){return this.beforeHooks.push(D),this}after(D){return this.afterHooks.push(D),this}use(D){return this.middleware.push(D),this}isMatched(D){if(this.aliasNames.includes(D))return!0;if(this.namespace)return`${this.namespace}:${this.name}`===D;return this.name===D}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof Ba}get displayName(){return this.namespace?`${this.namespace}:${this.name}`:this.name}hasOption(D){let t=Yo(D.split(".")[0]);return!!this.options.find((m)=>m.names.some((A)=>Yo(A)===t))}outputHelp(){let{name:D,commands:t}=this.cli,{versionNumber:m,options:A,helpCallback:_}=this.cli.globalCommand,z=[{body:`${D}${m?`/${m}`:""}`}];if(z.push({title:"Usage",body:` $ ${D} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let ne=Wl(t.map((ke)=>ke.rawName)),re=new Map,ie=[];for(let ke of t)if(ke.namespace){if(!re.has(ke.namespace))re.set(ke.namespace,[]);re.get(ke.namespace).push(ke)}else ie.push(ke);let ae="";if(ie.sort((ke,le)=>ke.rawName<le.rawName?-1:ke.rawName>le.rawName?1:0),ie.length>0)ae+=ie.map((ke)=>` ${Oa(ke.rawName,ne.length)} ${ke.description}`).join(`
@@ -28,7 +28,7 @@ Received ${m}, cleaning up...`),D)try{await D()}catch(A){console.error("Error du
28
28
  `)),this.enableDidYouMean){let t=[];for(let A of this.commands){if(A.displayName)t.push(A.displayName);if(A.aliasNames)t.push(...A.aliasNames)}let m=Kl(D,t);if(m.length>0)console.log(Vo.yellow("Did you mean one of these?")),m.forEach((A)=>console.log(` ${Vo.dim("•")} ${this.name} ${A}`)),console.log("")}console.log(Vo.dim("Run"),`${this.name} --help`,Vo.dim("to see all available commands")),ji.exit(1)}async parse(D=ql,t={}){let{run:m=!0,exitOnError:A=!1}=t;if(A)try{return await this.parse(D,{run:m})}catch(X){throw this.handleUsageError(X),X}if(this.rawArgs=D,!this.name)this.name=D[1]?zu(D[1]):"cli";let _=!0,z=D.slice(2),U=z[0];if(U&&!U.startsWith("-")){for(let X of this.commands)if(X.isMatched(U)){let ne=this.mri(z,X);_=!1;let re={...ne,args:ne.args.slice(1)};this.setParsedInfo(re,X,U),this.emit(`command:${U}`,X);break}if(_){let X=z[1];if(X&&!X.startsWith("-")){let ne=`${U}:${X}`;for(let re of this.commands)if(re.isMatched(ne)){let ie=this.mri(z,re);_=!1;let ae={...ie,args:ie.args.slice(2)};this.setParsedInfo(ae,re,ne),this.emit(`command:${ne}`,re);break}}}}if(_){for(let X of this.commands)if(X.name===""){_=!1;let ne=this.mri(z,X);this.setParsedInfo(ne,X),this.emit("command:!",X);break}}if(_){let X=this.mri(D.slice(2));this.setParsedInfo(X)}if(this.options.verbose)this.isVerbose=!0;if(this.options.quiet)this.isQuiet=!0;if(this.options.debug)this.isDebug=!0;if(this.options.noInteraction||this.options.interaction===!1)this.isNoInteraction=!0;if(this.options.env)this.environment=String(this.options.env);if(this.options.dryRun)this.isDryRun=!0;if(this.options.force)this.isForce=!0;if(this.options.noEmoji||this.options.emoji===!1)this.useEmoji=!1;if(this.options.theme)this.theme=String(this.options.theme);if(this.options.noCache||this.options.cache===!1)this.isNoCache=!0;if(this.options.help&&this.showHelpOnExit)this.outputHelp(),m=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),m=!1,this.unsetMatchedCommand();let Y={args:this.args,options:this.options};if(m)await this.runMatchedCommand();if(!this.matchedCommand&&this.args[0]){if(this.emit("command:*"),!(this.listenerCount("command:*")>0))this.showCommandNotFound(this.args[0])}return Y}mri(D,t){let m=[...this.globalCommand.options,...t?t.options:[]],A=Bu(m),_=[],z=D.indexOf("--");if(z>-1)_=D.slice(z+1),D=D.slice(0,z);let U=qu(D,A),Y={_:U._};for(let ae of Object.keys(U))if(ae!=="_")Y[Yo(ae)]=U[ae];let X=Y._,ne={"--":_},re=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,ie=Object.create(null);for(let ae of m){if(!re&&ae.config.default!==void 0)for(let be of ae.names)ne[be]=ae.config.default;if(Array.isArray(ae.config.type)){if(ie[ae.name]===void 0)ie[ae.name]={shouldTransform:!0,transformFunction:ae.config.type[0]}}}for(let ae of Object.keys(Y))if(ae!=="_"){let be=ae.split(".");_u(ne,be,Y[ae]),Mu(ne,ie)}return{args:X,options:ne}}async run(D=ql){return this.parse(D,{run:!0,exitOnError:!0})}handleUsageError(D){if(!Uu(D)||D.isUsageError===!1)return;let t=D.message||"command-line error",m=this.name?`${this.name}: `:"",A=/--help/.test(t)?"":D.usage?`
29
29
  Usage: ${D.usage}`:`
30
30
  Run \`${this.name??"cli"} --help\` for usage.`;ji.stderr.write(`${m}${t}${A}
31
- `),ji.exit(D.exitCode??2)}async runMatchedCommand(){let{args:D,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let A=[];m.args.forEach((Y,X)=>{if(Y.variadic)A.push(D.slice(X));else A.push(D[X])}),A.push(t);let _={command:m,args:A,options:t};for(let Y of m.beforeHooks)await Y(_);let z,U=async()=>{let Y=m.commandAction.apply(this,A);if(Y instanceof Promise)z=await Y;else z=Y;return z};if(m.middleware.length>0){let Y=0,X=async()=>{if(Y<m.middleware.length){let ne=m.middleware[Y++];await ne({..._,next:X})}else await U()};await X()}else await U();for(let Y of m.afterHooks)await Y(_);return z}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ji.removeAllListeners("SIGINT"),ji.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Yl{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(D){if(!this.enabled){this.misses++;return}let t=this.cache.get(D);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(D),this.misses++;return}return this.hits++,t.value}set(D,t,m=5000){if(!this.enabled)return;this.cache.set(D,{value:t,timestamp:Date.now(),ttl:m})}has(D){if(!this.enabled)return!1;let t=this.cache.get(D);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(D),!1;return!0}delete(D){this.cache.delete(D)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let D=Date.now();for(let[t,m]of this.cache.entries())if(D-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Jh=new Yl;function Zu(){if("FORCE_COLOR"in Ho.env)return Ho.env.FORCE_COLOR!=="0";if("NO_COLOR"in Ho.env||Ho.env.TERM==="dumb")return!1;if(Ho.platform==="win32")return!0;return Gl.isatty(1)&&Gl.isatty(2)}var Zl=Zu();function Xt(D,t){if(!Zl)return(m)=>m;return(m)=>D+m+t}var Qu=Xt("\x1B[0m","\x1B[0m"),Xu=Xt("\x1B[31m","\x1B[39m"),em=Xt("\x1B[32m","\x1B[39m"),tm=Xt("\x1B[33m","\x1B[39m"),nm=Xt("\x1B[34m","\x1B[39m"),rm=Xt("\x1B[35m","\x1B[39m"),im=Xt("\x1B[36m","\x1B[39m"),om=Xt("\x1B[37m","\x1B[39m"),sm=Xt("\x1B[90m","\x1B[39m"),am=Xt("\x1B[1m","\x1B[22m"),cm=Xt("\x1B[3m","\x1B[23m"),lm=Xt("\x1B[4m","\x1B[24m"),dm=Xt("\x1B[2m","\x1B[22m"),um=Xt("\x1B[7m","\x1B[27m"),mm=Xt("\x1B[8m","\x1B[28m"),pm=Xt("\x1B[9m","\x1B[29m"),fm=Xt("\x1B[41m","\x1B[49m"),gm=Xt("\x1B[42m","\x1B[49m"),hm=Xt("\x1B[43m","\x1B[49m"),ym=Xt("\x1B[44m","\x1B[49m"),vm=Xt("\x1B[45m","\x1B[49m"),bm=Xt("\x1B[46m","\x1B[49m"),wm=Xt("\x1B[47m","\x1B[49m"),Sm=Zl,Cm={reset:Qu,red:Xu,green:em,yellow:tm,blue:nm,magenta:rm,cyan:im,white:om,gray:sm,bold:am,italic:cm,underline:lm,dim:dm,inverse:um,hidden:mm,strikethrough:pm,bgRed:fm,bgGreen:gm,bgYellow:hm,bgBlue:ym,bgMagenta:vm,bgCyan:bm,bgWhite:wm,isColorSupported:Sm},$m=Cm,Am=["up","down","left","right","space","enter","cancel"],ty={actions:new Set(Am),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ny=km.platform.startsWith("win"),ry=Symbol("clapp:cancel");var Rm=Wu();var Qt=(D,t)=>Rm?D:t,iy=Qt("◆","*"),oy=Qt("■","x"),sy=Qt("▲","x"),ay=Qt("◇","o"),cy=Qt("┌","T"),Im=Qt("│","|"),ly=Qt("└","—"),dy=Qt("●",">"),uy=Qt("○"," "),my=Qt("◻","[•]"),py=Qt("◼","[+]"),fy=Qt("◻","[ ]"),gy=Qt("▪","•"),hy=Qt("─","-"),yy=Qt("╮","+"),vy=Qt("├","+"),by=Qt("╯","+"),wy=Qt("●","•"),Sy=Qt("◆","*"),Cy=Qt("▲","!"),$y=Qt("■","x");var ky={light:Qt("─","-"),heavy:Qt("━","="),block:Qt("█","#")};function Pm(){return`${$m.gray(Im)} `}var Ay=Pm();var Ma="0.16.50";function Ql(D,t,m=process.env){let A=t?.options.find((U)=>U.name==="profile");if((!A||/\baws\b/i.test(A.description))&&typeof D.profile==="string"&&D.profile)m.AWS_PROFILE=D.profile,delete m.AWS_ACCESS_KEY_ID,delete m.AWS_SECRET_ACCESS_KEY,delete m.AWS_SESSION_TOKEN;if(!t?.options.some((U)=>U.name==="region")&&typeof D.region==="string"&&D.region)m.AWS_REGION=D.region,m.AWS_DEFAULT_REGION=D.region}import{existsSync as za}from"node:fs";import{mkdir as xm,writeFile as Xl}from"node:fs/promises";function Ua(D){D.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server or serverless").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(t)=>{if(i("Initializing ts-cloud Project"),za("cloud.config.ts")){if(!await u("cloud.config.ts already exists. Overwrite?",!1)){e("Initialization cancelled");return}}let m=t?.name||await R("Project name","my-app"),A=t?.mode||await No("Select deployment mode",["serverless","server"]),_=t?.region||await No("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),z=new s("Creating configuration file...");z.start();let U=`import { defineConfig } from '@ts-cloud/core'
31
+ `),ji.exit(D.exitCode??2)}async runMatchedCommand(){let{args:D,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let A=[];m.args.forEach((Y,X)=>{if(Y.variadic)A.push(D.slice(X));else A.push(D[X])}),A.push(t);let _={command:m,args:A,options:t};for(let Y of m.beforeHooks)await Y(_);let z,U=async()=>{let Y=m.commandAction.apply(this,A);if(Y instanceof Promise)z=await Y;else z=Y;return z};if(m.middleware.length>0){let Y=0,X=async()=>{if(Y<m.middleware.length){let ne=m.middleware[Y++];await ne({..._,next:X})}else await U()};await X()}else await U();for(let Y of m.afterHooks)await Y(_);return z}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ji.removeAllListeners("SIGINT"),ji.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Yl{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(D){if(!this.enabled){this.misses++;return}let t=this.cache.get(D);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(D),this.misses++;return}return this.hits++,t.value}set(D,t,m=5000){if(!this.enabled)return;this.cache.set(D,{value:t,timestamp:Date.now(),ttl:m})}has(D){if(!this.enabled)return!1;let t=this.cache.get(D);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(D),!1;return!0}delete(D){this.cache.delete(D)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let D=Date.now();for(let[t,m]of this.cache.entries())if(D-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Jh=new Yl;function Zu(){if("FORCE_COLOR"in Ho.env)return Ho.env.FORCE_COLOR!=="0";if("NO_COLOR"in Ho.env||Ho.env.TERM==="dumb")return!1;if(Ho.platform==="win32")return!0;return Gl.isatty(1)&&Gl.isatty(2)}var Zl=Zu();function Xt(D,t){if(!Zl)return(m)=>m;return(m)=>D+m+t}var Qu=Xt("\x1B[0m","\x1B[0m"),Xu=Xt("\x1B[31m","\x1B[39m"),em=Xt("\x1B[32m","\x1B[39m"),tm=Xt("\x1B[33m","\x1B[39m"),nm=Xt("\x1B[34m","\x1B[39m"),rm=Xt("\x1B[35m","\x1B[39m"),im=Xt("\x1B[36m","\x1B[39m"),om=Xt("\x1B[37m","\x1B[39m"),sm=Xt("\x1B[90m","\x1B[39m"),am=Xt("\x1B[1m","\x1B[22m"),cm=Xt("\x1B[3m","\x1B[23m"),lm=Xt("\x1B[4m","\x1B[24m"),dm=Xt("\x1B[2m","\x1B[22m"),um=Xt("\x1B[7m","\x1B[27m"),mm=Xt("\x1B[8m","\x1B[28m"),pm=Xt("\x1B[9m","\x1B[29m"),fm=Xt("\x1B[41m","\x1B[49m"),gm=Xt("\x1B[42m","\x1B[49m"),hm=Xt("\x1B[43m","\x1B[49m"),ym=Xt("\x1B[44m","\x1B[49m"),vm=Xt("\x1B[45m","\x1B[49m"),bm=Xt("\x1B[46m","\x1B[49m"),wm=Xt("\x1B[47m","\x1B[49m"),Sm=Zl,Cm={reset:Qu,red:Xu,green:em,yellow:tm,blue:nm,magenta:rm,cyan:im,white:om,gray:sm,bold:am,italic:cm,underline:lm,dim:dm,inverse:um,hidden:mm,strikethrough:pm,bgRed:fm,bgGreen:gm,bgYellow:hm,bgBlue:ym,bgMagenta:vm,bgCyan:bm,bgWhite:wm,isColorSupported:Sm},$m=Cm,Am=["up","down","left","right","space","enter","cancel"],ty={actions:new Set(Am),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ny=km.platform.startsWith("win"),ry=Symbol("clapp:cancel");var Rm=Wu();var Qt=(D,t)=>Rm?D:t,iy=Qt("◆","*"),oy=Qt("■","x"),sy=Qt("▲","x"),ay=Qt("◇","o"),cy=Qt("┌","T"),Im=Qt("│","|"),ly=Qt("└","—"),dy=Qt("●",">"),uy=Qt("○"," "),my=Qt("◻","[•]"),py=Qt("◼","[+]"),fy=Qt("◻","[ ]"),gy=Qt("▪","•"),hy=Qt("─","-"),yy=Qt("╮","+"),vy=Qt("├","+"),by=Qt("╯","+"),wy=Qt("●","•"),Sy=Qt("◆","*"),Cy=Qt("▲","!"),$y=Qt("■","x");var ky={light:Qt("─","-"),heavy:Qt("━","="),block:Qt("█","#")};function Pm(){return`${$m.gray(Im)} `}var Ay=Pm();var Ma="0.16.51";function Ql(D,t,m=process.env){let A=t?.options.find((U)=>U.name==="profile");if((!A||/\baws\b/i.test(A.description))&&typeof D.profile==="string"&&D.profile)m.AWS_PROFILE=D.profile,delete m.AWS_ACCESS_KEY_ID,delete m.AWS_SECRET_ACCESS_KEY,delete m.AWS_SESSION_TOKEN;if(!t?.options.some((U)=>U.name==="region")&&typeof D.region==="string"&&D.region)m.AWS_REGION=D.region,m.AWS_DEFAULT_REGION=D.region}import{existsSync as za}from"node:fs";import{mkdir as xm,writeFile as Xl}from"node:fs/promises";function Ua(D){D.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server or serverless").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(t)=>{if(i("Initializing ts-cloud Project"),za("cloud.config.ts")){if(!await u("cloud.config.ts already exists. Overwrite?",!1)){e("Initialization cancelled");return}}let m=t?.name||await R("Project name","my-app"),A=t?.mode||await No("Select deployment mode",["serverless","server"]),_=t?.region||await No("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),z=new s("Creating configuration file...");z.start();let U=`import { defineConfig } from '@ts-cloud/core'
32
32
 
33
33
  export default defineConfig({
34
34
  project: {
@@ -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")}),D.command("init:server","Initialize server-based (EC2) project").action(async()=>{i("Initializing Server-Based Project"),await D.parse(["init","--mode","server"])}),D.command("init:serverless","Initialize serverless (Fargate/Lambda) project").action(async()=>{i("Initializing Serverless Project"),await D.parse(["init","--mode","serverless"])}),D.command("init:hybrid","Initialize hybrid project").action(async()=>{i("Initializing Hybrid Project"),await D.parse(["init","--mode","hybrid"])})}import{readFile as ed,writeFile as Em}from"node:fs/promises";import{resolve as Ms}from"node:path";async function De(){let D=await Gi();if(!D.project)throw Error("Missing required project configuration in cloud.config.ts");return D}function fn(D){if(D)switch(D.toLowerCase()){case"porkbun":{let A=process.env.PORKBUN_API_KEY,_=process.env.PORKBUN_SECRET_KEY;if(!A||!_)throw Error("PORKBUN_API_KEY and PORKBUN_SECRET_KEY environment variables are required for Porkbun provider");return{provider:"porkbun",apiKey:A,secretKey:_}}case"godaddy":{let A=process.env.GODADDY_API_KEY,_=process.env.GODADDY_API_SECRET;if(!A||!_)throw Error("GODADDY_API_KEY and GODADDY_API_SECRET environment variables are required for GoDaddy provider");let z=process.env.GODADDY_ENVIRONMENT||"production";return{provider:"godaddy",apiKey:A,apiSecret:_,environment:z}}case"route53":{let A=process.env.AWS_REGION||"us-east-1",_=process.env.AWS_HOSTED_ZONE_ID;return{provider:"route53",region:A,hostedZoneId:_}}case"cloudflare":{let A=process.env.CLOUDFLARE_API_TOKEN;if(!A)throw Error("CLOUDFLARE_API_TOKEN environment variable is required for Cloudflare provider");return{provider:"cloudflare",apiToken:A,zoneId:process.env.CLOUDFLARE_ZONE_ID,accountId:process.env.CLOUDFLARE_ACCOUNT_ID}}default:throw Error(`Unknown DNS provider: ${D}. Supported: porkbun, godaddy, route53, cloudflare`)}if(new Ai().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 Ur(D){let t=fn(D);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 M(t)}async function Tm(D){let t=await De(),m=y(process.cwd(),t),A=D??Object.keys(t.environments??{})[0]??"production",_=m.environments.get(A);if(!_)throw m.store.close(),Error(`Environment ${A} was not found.`);let z=t.project?.region??"us-east-1",U=x(process.cwd()),Y=new Nr(m.store),X=new $r(Y,{encryptionKey:U,backends:[new wt(m.store,U),new xr(new K(z),z),new _r(new We(z),z),new Or]}),ne=m.store.getActorByExternalId("system","cli")??m.store.createActor({kind:"system",externalId:"cli",displayName:"ts-cloud CLI"});return await yn(X,m,t,ne.id),{config:t,controlPlane:m,env:A,environmentRecord:_,store:Y,service:X,actor:ne}}async function Vr(D,t){let m=await Tm(D);try{return await t(m)}finally{m.controlPlane.store.close()}}async function An(D){try{await D()}catch(t){r(t instanceof Error?t.message:String(t))}}function Nm(D){return D.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 td(D,t=process.env){if(D.value!=null)throw Error("Secret values are not accepted in command arguments; use --from-env or the interactive prompt.");if(!D.fromEnv)return;let m=t[D.fromEnv];if(!m)throw Error(`${D.fromEnv} is empty or unavailable.`);return m}function vr(D,t){let m=t.scope??"environment";if(m==="project")return{type:m,id:D.controlPlane.project.id};if(m==="environment"){let A=t.target?D.controlPlane.store.listEnvironments(D.controlPlane.project.id).find((_)=>_.id===t.target||_.slug===t.target):D.environmentRecord;if(!A)throw Error(`Environment ${t.target} was not found.`);return{type:m,id:A.id,environmentId:A.id}}if(m==="service"){let A=D.controlPlane.store.listResources(D.controlPlane.project.id),_=A.find((z)=>z.id===t.target||z.slug===t.target);if(!_)throw Error("Service scope requires --target with a resource ID or slug.");return{type:m,id:_.id,environmentId:_.environmentId,resourceId:_.id}}if(m==="function"){let A=D.controlPlane.store.listResources(D.controlPlane.project.id),_=A.find((z)=>z.kind==="function"&&(z.id===t.target||z.slug===t.target));if(!_)throw Error("Function scope requires --target with a function resource ID or slug.");return{type:m,id:_.id,environmentId:_.environmentId,resourceId:_.id}}if(m==="preview"){let A=new Fe(D.controlPlane.store).listInstances({projectId:D.controlPlane.project.id}).find((_)=>_.id===t.target||_.name===t.target);if(!A)throw Error("Preview scope requires --target with a preview ID or name.");return{type:m,id:A.id,environmentId:A.baseEnvironmentId,resourceId:A.resourceId,previewId:A.id}}throw Error("--scope must be project, environment, service, function, or preview.")}function Wa(D){let t=D??"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 ko(D,t,m){let A=D.store.find(D.controlPlane.project.id,m,t);if(!A)throw Error(`${t} was not found in the selected scope.`);return A}async function Om(D,t){if(D==="secret")return td(t)??await R("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 R("Enter variable value","")}function li(D){return D.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 Va(D){D.command("config","Show validated file configuration").action(async()=>An(async()=>{let t=await De();console.log(JSON.stringify(t,null,2))})),D.command("config:validate","Validate configuration file").action(async()=>An(async()=>{let t=await De();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"}`)})),li(D.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)=>An(async()=>Vr(t.env,async(m)=>{let A=vr(m,t),_=["variable","secret"].includes(t.kind??"")?t.kind:void 0,z=m.service.list({projectId:m.controlPlane.project.id,scope:A,kind:_,search:t.search,canReadSecretMetadata:!0});if(t.json)console.log(JSON.stringify(z,null,2));else c(["Key","Kind","Scope","Precedence","Value/backend","Backend version","Requirement","Updated"],Nm(z))}))),li(D.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)=>An(async()=>Vr(m.env,async(A)=>{let _=vr(A,m),z=m.secret?"secret":"variable",U=z==="secret"?Wa(m.backend):void 0,Y=U==="external"?void 0:await Om(z,m),X=await A.service.set({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,scope:_,key:t,kind:z,value:Y,reference:m.reference,backend:U,required:!!m.required,confirmed:m.confirm===t,actorId:A.actor.id,idempotencyKey:`cli:${crypto.randomUUID()}`});if(m.json)console.log(JSON.stringify({entry:A.service.list({projectId:A.controlPlane.project.id,scope:_,canReadSecretMetadata:!0}).find((ne)=>ne.id===X.entry.id),mutation:X.mutation,warnings:X.warnings},null,2));else n(`${t}: ${X.mutation.added.length?"created":X.mutation.changed.length?"updated":"unchanged"}; ${X.mutation.affectedResourceIds.length} affected service(s).`)}))),li(D.command("config:delete <key>","Delete a scoped variable or secret")).option("--confirm <key>","Exact key confirmation").action(async(t,m)=>An(async()=>Vr(m.env,async(A)=>{let _=ko(A,t,vr(A,m));await A.service.remove({entryId:_.id,expectedVersion:_.version,confirmed:m.confirm===t,actorId:A.actor.id}),n(`Deleted ${t}.`)}))),li(D.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)=>An(async()=>Vr(m.env,async(A)=>{let _=await A.service.importDotenv({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,scope:vr(A,m),source:await ed(Ms(t),"utf8"),secretKeys:m.secretKeys?.split(",").map((z)=>z.trim()).filter(Boolean),backend:Wa(m.backend),confirmed:m.confirm==="import",actorId:A.actor.id,idempotencyKey:`cli-import:${crypto.randomUUID()}`});if(!_.document.valid)throw Error(_.document.diagnostics.map((z)=>`line ${z.line}: ${z.message}`).join(`
68
- `));if(m.json)console.log(JSON.stringify({mutation:_.mutation,diagnostics:_.document.diagnostics,warnings:_.warnings},null,2));else n(`Imported ${_.mutation?.added.length??0} new, ${_.mutation?.changed.length??0} changed, and ${_.mutation?.unchanged.length??0} unchanged entries.`)}))),li(D.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)=>An(async()=>Vr(m.env,async(A)=>{let{parseDotenv:_}=await import("./chunk-xaqkj8fn.js"),z=_(await ed(Ms(t),"utf8"));if(!z.valid)throw Error(z.diagnostics.map((Y)=>`line ${Y.line}: ${Y.message}`).join(`
68
+ `));if(m.json)console.log(JSON.stringify({mutation:_.mutation,diagnostics:_.document.diagnostics,warnings:_.warnings},null,2));else n(`Imported ${_.mutation?.added.length??0} new, ${_.mutation?.changed.length??0} changed, and ${_.mutation?.unchanged.length??0} unchanged entries.`)}))),li(D.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)=>An(async()=>Vr(m.env,async(A)=>{let{parseDotenv:_}=await import("./chunk-p6wxv8yq.js"),z=_(await ed(Ms(t),"utf8"));if(!z.valid)throw Error(z.diagnostics.map((Y)=>`line ${Y.line}: ${Y.message}`).join(`
69
69
  `));let U=A.service.plan({projectId:A.controlPlane.project.id,scope:vr(A,m),values:z.values,removeMissing:!!m.removeMissing});if(m.json)console.log(JSON.stringify(U,null,2));else c(["Action","Keys"],[["Add",U.added.join(", ")||"—"],["Change",U.changed.join(", ")||"—"],["Remove",U.removed.join(", ")||"—"],["Unchanged",U.unchanged.join(", ")||"—"]]),e(`${U.affectedResourceIds.length} affected service(s); no secret values were printed.`)}))),li(D.command("config:export [file]","Export plaintext variables only as dotenv")).action(async(t,m)=>An(async()=>Vr(m.env,async(A)=>{let _=A.service.exportVariables({projectId:A.controlPlane.project.id,scope:vr(A,m)});if(t)await Em(Ms(t),_,{mode:384}),n(`Exported variables to ${Ms(t)}; secrets were excluded.`);else process.stdout.write(_)}))),li(D.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)=>An(async()=>Vr(m.env,async(A)=>{let _=vr(A,m),z=ko(A,t,_),U=vr(A,{env:m.env,scope:m.toScope,target:m.toTarget}),Y=await A.service.transfer({entryId:z.id,targetScope:U,mode:m.move?"move":"copy",confirmed:m.confirm===t,actorId:A.actor.id,idempotencyKey:`cli-transfer:${crypto.randomUUID()}`});n(`${t} ${m.move?"moved":"copied"}; ${Y.mutation.affectedResourceIds.length} affected service(s).`)}))),li(D.command("config:reveal <key>","Reveal a secret after exact confirmation")).option("--confirm <key>","Exact key confirmation").action(async(t,m)=>An(async()=>Vr(m.env,async(A)=>{if(m.confirm!==t)throw Error(`Use --confirm ${t} to reveal this secret.`);let _=ko(A,t,vr(A,m));console.log(await A.service.reveal({entryId:_.id,canRevealSecrets:!0,recentlyAuthenticated:!0,actorId:A.actor.id}))}))),li(D.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)=>An(async()=>Vr(t.environment??t.env,async(m)=>{let A=vr(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:A,kind:"variable"}).map((_)=>[_.key,_.value??"",_.updatedAt]));else if(t.set){let _=t.set.indexOf("=");if(_<1)throw Error("Use --set KEY=VALUE.");let z=t.set.slice(0,_),U=t.set.slice(_+1);await m.service.set({organizationId:m.controlPlane.organization.id,projectId:m.controlPlane.project.id,scope:A,key:z,kind:"variable",value:U,confirmed:!1,actorId:m.actor.id}),n(`Set ${z}.`)}else if(t.unset){let _=ko(m,t.unset,A);await m.service.remove({entryId:_.id,expectedVersion:_.version,confirmed:await u(`Delete ${_.key}?`,!1),actorId:m.actor.id}),n(`Deleted ${_.key}.`)}else e("Use --list, --set KEY=VALUE, or --unset KEY.")}))),li(D.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)=>An(async()=>Vr(t.env,async(m)=>{let A=vr(m,t);if(t.list)c(["Key","Backend","Version","Rotated"],m.service.list({projectId:m.controlPlane.project.id,scope:A,kind:"secret",canReadSecretMetadata:!0}).map((_)=>[_.key,_.backend??"restricted",_.backendVersion??"—",_.rotatedAt??"never"]));else if(t.create||t.update){let _=t.create??t.update,z=td(t)??await R("Enter secret value (write-only)","");await m.service.set({organizationId:m.controlPlane.organization.id,projectId:m.controlPlane.project.id,scope:A,key:_,kind:"secret",value:z,backend:Wa(t.backend),confirmed:t.confirm===_,actorId:m.actor.id}),n(`${_} ${t.update?"rotated":"created"}.`)}else if(t.get){if(t.confirm!==t.get)throw Error(`Use --confirm ${t.get} to reveal.`);let _=ko(m,t.get,A);console.log(await m.service.reveal({entryId:_.id,canRevealSecrets:!0,recentlyAuthenticated:!0,actorId:m.actor.id}))}else if(t.delete){let _=ko(m,t.delete,A);await m.service.remove({entryId:_.id,expectedVersion:_.version,confirmed:t.confirm===_.key,actorId:m.actor.id}),n(`Deleted ${_.key}.`)}else e("Use --list, --create, --update, --get, or --delete.")})))}import{existsSync as Hm}from"node:fs";import{readFile as Km,writeFile as Jm}from"node:fs/promises";async function Us(D){let t=[];for(let m of D.steps)try{t.push({step:m,state:await m.satisfied()?"satisfied":"pending"})}catch(A){t.push({step:m,state:"unknown",reason:A instanceof Error?A.message:String(A)})}return t}function nd(D){return D.filter((t)=>t.state!=="satisfied")}function Lm(D){return nd(D).some((t)=>t.step.destructive===!0)}function qs(D,t){let m=nd(t),A=[`${D.operation} ${D.target}`];if(m.length===0)return A.push(" Nothing to do — every step is already satisfied."),A;for(let{step:z,state:U,reason:Y}of t){let X=U==="satisfied"?"ok ":U==="unknown"?"? ":"→ ",ne=[z.destructive?"DESTRUCTIVE":"",U==="satisfied"?"already done":""].filter(Boolean);if(A.push(` ${X}${z.title}${ne.length>0?` [${ne.join(", ")}]`:""}`),z.change)A.push(` ${z.change.from} → ${z.change.to}`);if(Y)A.push(` could not check: ${Y}`)}let _=m.filter((z)=>z.step.destructive).length;return A.push(` ${m.length} step(s) would run`+(_>0?`, ${_} irreversible — re-run with --confirm ${D.target}`:"")),A}async function Gs(D,t,m={}){let A={operation:D.operation,target:D.target,steps:[],success:!0};if(Lm(t)&&m.confirm!==D.target)throw Error(`${D.operation} includes an irreversible step. Re-run with --confirm ${D.target} to authorize it.`);for(let{step:_,state:z}of t){if(z==="satisfied"){A.steps.push({id:_.id,title:_.title,state:"skipped"}),m.log?.(`skip ${_.title} (already done)`);continue}m.audit?.({operation:D.operation,target:D.target,step:_.id,state:"started"});try{await _.apply(),A.steps.push({id:_.id,title:_.title,state:"applied"}),m.log?.(`done ${_.title}`),m.audit?.({operation:D.operation,target:D.target,step:_.id,state:"applied"})}catch(U){let Y=U instanceof Error?U.message:String(U);return A.steps.push({id:_.id,title:_.title,state:"failed",error:Y}),A.success=!1,m.log?.(`FAIL ${_.title}: ${Y}`),m.audit?.({operation:D.operation,target:D.target,step:_.id,state:"failed",error:Y}),A}}return A}function Ao(D,t){return`/tmp/ts-cloud-move-${D}-${t}.tar.gz`}function rd(D,t){return`${D}-${t}*.service`}function Vt(D){return`'${D.split("'").join("'\\''")}'`}function Fm(D,t){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${Vt(id(D,t))} || true); do`,' systemctl stop "$unit" 2>/dev/null || true',"done"].join(`
70
70
  `)}function id(D,t){return`^${D}-${t}-((queue|daemon)-.*|scheduler)\\.service$`}function jm(D,t){return od(id(D,t))}function od(D){return[`ls /etc/systemd/system/ 2>/dev/null | grep -E ${Vt(D)} | while read -r unit; do`,' systemctl is-active "$unit" >/dev/null 2>&1 && echo "active:$unit" || true',"done"].join(`
71
71
  `)}function Bm(D){return!D.split(`
@@ -309,13 +309,13 @@ ${t.loadManagement?.enabled?`
309
309
  Generated ${Se} resources:`);let Ae=Pe.getResources(),Re={};for(let Ne of Object.values(Ae)){let je=Ne.Type;Re[je]=(Re[je]||0)+1}let ze=Object.entries(Re).sort((Ne,je)=>je[1]-Ne[1]);for(let[Ne,je]of ze)e(` - ${Ne}: ${je}`);e(`
310
310
  Next steps:
311
311
  1. Review the generated templates in ${_}/
312
- 2. Run 'cloud deploy' to deploy your infrastructure`)}catch(A){m.fail("Failed to generate templates"),r(A instanceof Error?A.message:"Unknown error")}}),D.command("generate:preview","Preview what will be generated").action(async()=>{Rn("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."})}),D.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 De(),A=t?.env||"production",{resolveProjectStackName:_}=await import("./chunk-e6ewfmbp.js"),z=t?.stack||_(m,A),U=m.project.region||"us-east-1";e(`Stack: ${z}`),e(`Region: ${U}`),e(`Environment: ${A}`),d("Generating template from configuration...");let Y=new Io({config:m,environment:A});Y.generate();let X=Y.toJSON(),ne=JSON.parse(X);d("Fetching deployed template...");let re=new v(U),ie=null;try{let Ae=await re.getTemplate(z);if(Ae.TemplateBody)ie=JSON.parse(Ae.TemplateBody)}catch(Ae){if(Ae.message?.includes("does not exist")){a(`Stack "${z}" does not exist yet`),e(`
312
+ 2. Run 'cloud deploy' to deploy your infrastructure`)}catch(A){m.fail("Failed to generate templates"),r(A instanceof Error?A.message:"Unknown error")}}),D.command("generate:preview","Preview what will be generated").action(async()=>{Rn("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."})}),D.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 De(),A=t?.env||"production",{resolveProjectStackName:_}=await import("./chunk-83brtkvn.js"),z=t?.stack||_(m,A),U=m.project.region||"us-east-1";e(`Stack: ${z}`),e(`Region: ${U}`),e(`Environment: ${A}`),d("Generating template from configuration...");let Y=new Io({config:m,environment:A});Y.generate();let X=Y.toJSON(),ne=JSON.parse(X);d("Fetching deployed template...");let re=new v(U),ie=null;try{let Ae=await re.getTemplate(z);if(Ae.TemplateBody)ie=JSON.parse(Ae.TemplateBody)}catch(Ae){if(Ae.message?.includes("does not exist")){a(`Stack "${z}" does not exist yet`),e(`
313
313
  This will be a new deployment with the following resources:`);let Re=Object.keys(ne.Resources||{}).length;e(`
314
314
  Resources to create: ${Re}`);let ze={};for(let Ne of Object.values(ne.Resources||{})){let je=Ne.Type;ze[je]=(ze[je]||0)+1}for(let[Ne,je]of Object.entries(ze).sort((Ue,Ct)=>Ct[1]-Ue[1]))e(` + ${Ne}: ${je}`);e("\nRun `cloud deploy` to create this stack");return}throw Ae}d("Comparing templates...");let ae=ie.Resources||{},be=ne.Resources||{},ke=new Set(Object.keys(ae)),le=new Set(Object.keys(be)),$e=[];for(let Ae of le)if(!ke.has(Ae))$e.push(Ae);let Pe=[];for(let Ae of ke)if(!le.has(Ae))Pe.push(Ae);let Se=[];for(let Ae of le)if(ke.has(Ae)){let Re=JSON.stringify(ae[Ae]),ze=JSON.stringify(be[Ae]);if(Re!==ze)Se.push(Ae)}if($e.length===0&&Pe.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
  `),$e.length>0){n(`Resources to add (${$e.length}):`);for(let Ae of $e){let Re=be[Ae].Type;e(` + ${Ae} (${Re})`)}console.log()}if(Pe.length>0){r(`Resources to remove (${Pe.length}):`);for(let Ae of Pe){let Re=ae[Ae].Type;e(` - ${Ae} (${Re})`)}console.log()}if(Se.length>0){a(`Resources to modify (${Se.length}):`);for(let Ae of Se){let Re=be[Ae].Type;e(` ~ ${Ae} (${Re})`)}console.log()}e("Summary:"),e(` - Add: ${$e.length}`),e(` - Remove: ${Pe.length}`),e(` - Modify: ${Se.length}`),e("\nRun `cloud deploy` to apply these changes")}catch(m){r(`Diff failed: ${m.message}`)}})}function _i(D,t=0){let m=Number(D);return Number.isFinite(m)?m:t}function Ja(D){return _i(D)*1024}function cp(D){let t=D?.date?.trim(),m=D?.time?.trim();if(!t||!m)return null;let A=new Date(`${t}T${m}Z`);return Number.isFinite(A.getTime())?A.toISOString():null}function lp(D,t,m){let A;try{A=JSON.parse(D)}catch{return[]}let _=(A?.sysstat?.hosts??[]).flatMap((U)=>U.statistics??[]),z=[];for(let U of _){let Y=cp(U.timestamp);if(!Y)continue;let X=new Date(Y).getTime();if(X<t.getTime()||X>m.getTime())continue;let ne=U["cpu-load"]?.find((ie)=>ie.cpu==="all")??U["cpu-load"]?.[0],re=_i(ne?.idle,100);z.push({timestamp:Y,cpuUsedPercent:Math.max(0,Math.min(100,100-re)),cpuUserPercent:_i(ne?.user),cpuSystemPercent:_i(ne?.system),cpuIowaitPercent:_i(ne?.iowait),memoryUsedPercent:_i(U.memory?.["memused-percent"]),memoryUsedBytes:Ja(U.memory?.memused),memoryAvailableBytes:Ja(U.memory?.avail),swapUsedPercent:_i(U.memory?.["swpused-percent"]),swapUsedBytes:Ja(U.memory?.swpused)})}return z.sort((U,Y)=>U.timestamp.localeCompare(Y.timestamp))}function dp(D){return Object.fromEntries(Object.entries(D.time_series??{}).map(([t,m])=>[t,(m.values??[]).map(([A,_])=>({timestamp:new Date(Number(A)*1000).toISOString(),value:_i(_,Number.NaN)})).filter((A)=>Number.isFinite(A.value))]))}function pd(D){return D.length?D.reduce((t,m)=>t+m,0)/D.length:null}function Ya(D){return D.length?Math.max(...D):null}function up(D){return D.length?Math.min(...D):null}async function fd(D){let[t,m]=await Promise.all([D.client.getServerMetrics(D.serverId,{types:["cpu","disk","network"],start:D.from,end:D.to,step:D.step}),_e(D.remote.host,"LC_ALL=C sadf -j -- -u -r -S",D.remote).catch(()=>"")]),A=lp(m,D.from,D.to),_=dp(t),U=(_.cpu??[]).map((ie)=>Math.max(0,Math.min(100,ie.value/Math.max(1,D.cores)))),Y=A.map((ie)=>ie.cpuUsedPercent),X=U.length?U:Y,ne=A.map((ie)=>ie.memoryUsedPercent),re=A.map((ie)=>ie.swapUsedPercent);return{from:D.from.toISOString(),to:D.to.toISOString(),cores:D.cores,host:A,provider:_,summary:{cpuAveragePercent:pd(X),cpuPeakPercent:Ya(X),memoryAveragePercent:pd(ne),memoryPeakPercent:Ya(ne),memoryMinimumAvailableBytes:up(A.map((ie)=>ie.memoryAvailableBytes)),swapPeakPercent:Ya(re)}}}function mp(D){if(D.length===0)throw Error("A server name cannot be empty.");if(D.length>253)throw Error(`'${D}' is longer than the 253 characters a hostname allows.`);for(let t of D.split(".")){if(t.length===0)throw Error(`'${D}' has an empty label — a hostname cannot contain '..'.`);if(t.length>63)throw Error(`'${t}' is longer than the 63 characters a hostname label allows.`);if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(t))throw Error(`'${t}' is not a valid hostname label. Use letters, digits and hyphens, not starting or ending with a hyphen.`)}}async function gd(D,t,m){if(mp(t),D===t)throw Error(`'${D}' is already named that.`);if((await m.takenNames()).some((z)=>z===t&&z!==D))throw Error(`'${t}' is already taken. Server names have to be unique within a provider project.`);let _=[];if(m.providerName&&m.renameProvider){let{providerName:z,renameProvider:U}=m;_.push({id:"provider",title:"Rename the server at the provider",change:{from:D,to:t},satisfied:async()=>await z()===t,apply:()=>U(t)})}if(m.stateName&&m.writeStateName){let{stateName:z,writeStateName:U}=m;_.push({id:"state-pin",title:"Update the recorded name in the local driver state",change:{from:D,to:t},satisfied:async()=>{let Y=await z();return Y===void 0||Y===t},apply:()=>U(t)})}if(m.remoteHostname&&m.setRemoteHostname){let{remoteHostname:z,setRemoteHostname:U}=m;_.push({id:"hostname",title:"Set the hostname on the box",change:{from:D,to:t},satisfied:async()=>await z()===t,apply:()=>U(t)})}return _.push({id:"inventory",title:"Rename the fleet inventory record",change:{from:D,to:t},satisfied:async()=>m.inventoryName()===t,apply:async()=>{await m.renameInventory(t)}}),{operation:"server:rename",target:D,steps:_}}function hd(D){let t=`'${D.replace(/'/g,`'"'"'`)}'`;return["set -eu",'TS_CLOUD_OLD="$(hostname)"',`hostnamectl set-hostname ${t} 2>/dev/null || { echo ${t} > /etc/hostname && hostname ${t}; }`,'if grep -q "^127.0.1.1" /etc/hosts; then',` TS_CLOUD_HOSTS="$(sed -E "s/^127\\.0\\.1\\.1.*/127.0.1.1\\t${D}/" /etc/hosts)"`,` printf '%s\\n' "$TS_CLOUD_HOSTS" > /etc/hosts`,"else",` printf '127.0.1.1\\t%s\\n' ${t} >> /etc/hosts`,"fi",'printf "%s -> %s\\n" "$TS_CLOUD_OLD" "$(hostname)"'].join(`
318
- `)}async function pp(){let D=await De(),t=y(process.cwd(),D),m=new xe(t.store),A=new On(m,[new st("aws"),new st("hetzner"),new st("ssh")]);return{controlPlane:t,store:m,service:A}}async function mi(D){let t=await pp();try{return await D(t)}finally{t.controlPlane.store.close()}}var Mi=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},vn=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};function Za(D,t){let m=Number.parseInt(D??"",10);return Number.isFinite(m)&&m>=0?m:t}function fp(D="3h"){let t=D.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ts(D,t="%"){return D==null?"unavailable":`${D.toFixed(1)}${t}`}async function gp(D,t){let m=await De();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await ge(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to read ${D}: project state is pinned to ${z.serverName}.`);let U=ur(m),Y=new Je({apiToken:pr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=new Date,ie=new Date(re.getTime()-fp(t.range)),ae=Math.min(3600,Math.max(60,Za(t.step,60))),be=await fd({client:Y,serverId:X.id,cores:Math.max(1,Number(X.server_type.cores)||1),from:ie,to:re,step:ae,remote:{host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:X.name,result:be},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[X.name,`${be.from} to ${be.to}`,`${ts(be.summary.cpuAveragePercent)} / ${ts(be.summary.cpuPeakPercent)}`,`${ts(be.summary.memoryAveragePercent)} / ${ts(be.summary.memoryPeakPercent)}`,be.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(be.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ts(be.summary.swapPeakPercent)]])}function yd(D){let t=D.targetType.prices?.find((m)=>m.location===D.location);return{serverId:D.serverId,serverName:D.serverName,location:D.location,from:D.currentType.name,to:D.targetType.name,capacityAvailable:D.capacityAvailable,alreadyComplete:D.alreadyComplete,upgradeDisk:D.upgradeDisk,target:{cores:D.targetType.cores,memoryGb:D.targetType.memory,diskGb:D.targetType.disk,architecture:D.targetType.architecture,cpuType:D.targetType.cpu_type},price:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function hp(D){let t=yd(D);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function yp(D,t,m){let A=await De();if(A.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let _=m.env??process.env.CLOUD_ENV??"production",z=T(A,_),U=await ge(z),Y=ur(A),X=new Je({apiToken:pr(Y.apiToken,A)}),re=U&&(D===U.serverName||D===String(U.serverId)||D===U.stackName)?await X.getServer(U.serverId):(await X.listServers()).find((Ne)=>Ne.name===D||String(Ne.id)===D);if(!re)throw Error(`Hetzner server ${D} was not found.`);if(U?.serverId&&U.serverId!==re.id)throw Error(`Refusing to resize ${D}: project state is pinned to server ${U.serverId}.`);let ie=pt(t),ae=m.upgradeDisk!==!1,be=await ui(X,re.id,ie,ae);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:yd(be)},null,2));else hp(be);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${re.name} to execute.`);return}if(m.confirm!==re.name)throw Error(`Resize requires --confirm ${re.name}.`);let ke=U?.publicIp??re.public_net.ipv4?.ip;if(!ke)throw Error(`Server ${re.name} has no public IPv4 address for verification.`);let le={host:ke,user:U?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},$e=await ps(z),Pe=new Date().toISOString(),Se={schemaVersion:1,operationId:$e?.targetType===ie&&$e.serverId===re.id?$e.operationId:crypto.randomUUID(),stackName:z,serverId:re.id,serverName:re.name,sourceType:be.currentType.name,targetType:ie,upgradeDisk:ae,phase:"planning",status:"running",attempts:$e?.targetType===ie?$e.attempts:0,startedAt:$e?.targetType===ie?$e.startedAt:Pe,updatedAt:Pe,manifest:$e?.targetType===ie?$e.manifest:void 0};await gt(Se);let Ae=Za(m.pollSeconds,900)*1000,Re=Za(m.maxWaitMinutes,0)*60000,ze=Date.now();for(;;){let Ne=await ui(X,re.id,ie,ae);if(!Ne.capacityAvailable&&!Ne.alreadyComplete){if(Se={...Se,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await gt(Se),!m.wait){if(!m.json)e(`${ie} has no capacity in ${Ne.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Re>0&&Date.now()-ze>=Re)throw Error(`Timed out waiting for ${ie} capacity in ${Ne.location}.`);if(!m.json)e(`Waiting ${Math.round(Ae/1000)} seconds for ${ie} capacity...`);await Bun.sleep(Ae);continue}let je=await ms(z);try{let Ue=await(async()=>{try{return Se={...Se,status:"running",attempts:Se.attempts+1,updatedAt:new Date().toISOString()},await gt(Se),await ss({client:X,serverId:re.id,targetType:ie,upgradeDisk:ae,resumeFromOff:Se.phase==="shutting-down"||Se.phase==="resizing"||Se.phase==="powering-on"||Se.phase==="verifying",manifest:Se.manifest,hooks:{preflight:async()=>{let Ct=await as(le);return Se={...Se,manifest:Ct,updatedAt:new Date().toISOString()},await gt(Se),Ct},afterBoot:async(Ct,At,rt,kt)=>cs(le,At,rt,kt),onPhase:async(Ct,At)=>{if(Se={...Se,phase:Ct,status:Ct==="waiting-capacity"?"waiting-capacity":Ct==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await gt(Se),!m.json)e(`${Ct}${At?` ${JSON.stringify(At)}`:""}`)}}})}finally{await je()}})();if(Se={...Se,status:Ue.status==="completed"||Ue.status==="already-complete"?"completed":Ue.status==="recovered"?"recovered":"waiting-capacity",lastError:Ue.status==="recovered"?Ue.error:void 0,updatedAt:new Date().toISOString()},await gt(Se),m.json)console.log(JSON.stringify({schemaVersion:1,result:Ue},null,2));else if(Ue.status==="completed"||Ue.status==="already-complete")n(`${re.name} is on ${ie} and passed full post-boot verification.`);else if(Ue.status==="recovered"&&Ue.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(Ae/1000)} seconds before retry.`),await Bun.sleep(Ae);continue}else if(Ue.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${Ue.error}`);return}catch(Ue){throw Se={...Se,status:"failed",lastError:Ue instanceof Error?Ue.message:String(Ue),updatedAt:new Date().toISOString()},await gt(Se),Ue}}}async function vp(D,t){let m=await De();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await ge(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to optimize ${D}: project state is pinned to ${z.serverName}.`);let U=ur(m),Y=new Je({apiToken:pr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=no(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:X.name,plan:re},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[X.name,re.firewallPorts.join(","),re.monitoring?"on":"off",re.autoUpdates?"on":"off",`${re.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${X.name} to execute.`);return}if(t.confirm!==X.name)throw Error(`Optimization requires --confirm ${X.name}.`);let ie={host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15},ae=await nn(ie),be=ae.routeProbes.filter((rt)=>!rt.ok),ke=m.infrastructure?.compute,le=Z(ke)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,$e=ae.failedUnits.filter((rt)=>!le.has(rt));if($e.length>0)throw Error(`Preflight found failed services: ${$e.join(", ")}`);if(be.length>0)throw Error(`Preflight found unhealthy routes: ${be.map((rt)=>rt.domain).join(", ")}`);let Pe=Z(ke)?[]:Object.values(m.sites??{}).flatMap((rt)=>typeof rt?.port==="number"&&![80,443].includes(rt.port)?[rt.port]:[]),Se=tn({allowSsh:ke?.allowSsh!==!1,sitePorts:Pe,allowedPorts:ke?.firewall?.allowedPorts}),Ae=(z.firewallId?(await Y.listFirewalls()).find((rt)=>rt.id===z.firewallId):void 0)??(await Y.listFirewalls()).find((rt)=>rt.name===`${m.project.slug}-${A}-app-fw`);if(!Ae)throw Error(`Managed firewall for ${X.name} was not found.`);let Re=await Y.setFirewallRules(Ae.id,Se);await Promise.all(Re.map((rt)=>Y.waitForAction(rt.id))),await ls(m,ie);let[ze,Ne]=await Promise.all([nn(ie),ds(ie)]),je=us(re,Ne),Ue=gc(ae,ze),Ct=ze.routeProbes.filter((rt)=>!rt.ok);if(Ue.stoppedServices.length>0)je.push(`services stopped: ${Ue.stoppedServices.join(", ")}`);if(Ue.changedRouteFragments.length>0)je.push(`route fragments changed: ${Ue.changedRouteFragments.join(", ")}`);if(Ue.missingRouteIds.length>0)je.push(`routes disappeared: ${Ue.missingRouteIds.join(", ")}`);if(Ue.changedReleaseLinks.length>0)je.push(`release links changed: ${Ue.changedReleaseLinks.join(", ")}`);if(Ue.missingData.length>0)je.push(`databases or volumes disappeared: ${Ue.missingData.join(", ")}`);if(Ct.length>0)je.push(`unhealthy routes: ${Ct.map((rt)=>rt.domain).join(", ")}`);if(je.length>0)throw Error(`Host optimization verification failed: ${je.join("; ")}`);let At={serverId:X.id,serverName:X.name,services:ze.runningServices.length,routes:ze.routeIds.length,healthyDomains:ze.routeProbes.length,releaseLinks:ze.releaseLinks.length,databasesAndVolumes:ze.dataCatalog.length,report:Ne};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:At},null,2));else n(`${X.name} passed full host, rpx route, service, release, and data verification.`)}async function bp(D,t,m){let A=await De(),_=m.env??"production",z=T(A,_);await mi(async(U)=>{let Y=Mi(U,D),X=U.store.list(U.controlPlane.project.id,!0),ne=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let Ae=ur(A);return new Je({apiToken:pr(Ae.apiToken,A)})}catch{return null}})():null,re=Y.providerId?Number(Y.providerId):Number.NaN,ie=await ge(z),ae=ie!=null&&ie.serverId===re,be=new zr,ke=Y.trustState==="pinned",le={takenNames:async()=>{let Ae=X.map((Re)=>Re.name);if(ne)Ae.push(...(await ne.listServers()).map((Re)=>Re.name));return Ae},inventoryName:()=>U.store.get(Y.id)?.name??Y.name,renameInventory:(Ae)=>{U.store.update(Y.id,{name:Ae})},...ne&&Number.isFinite(re)?{providerName:async()=>(await ne.getServer(re)).name,renameProvider:async(Ae)=>{await ne.renameServer(re,Ae)}}:{},...ae?{stateName:async()=>(await ge(z))?.serverName,writeStateName:async(Ae)=>{let Re=await ge(z);if(Re)await mt(z,{...Re,serverName:Ae})}}:{},...ke?{remoteHostname:async()=>{let Ae=await be.exec(Y,"hostname");return Ae.code===0?Ae.stdout.trim():void 0},setRemoteHostname:async(Ae)=>{let Re=await be.exec(Y,hd(Ae));if(Re.code!==0)throw Error(Re.stderr.trim()||`hostname exited ${Re.code}`)}}:{}},$e=await gd(Y.name,t,le),Pe=await Us($e);if(!m.apply){let Ae=[ne?"":"provider record (no provider id or no API token)",ae?"":"local state pin (none points at this server)",ke?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:$e.operation,target:$e.target,rename:{from:Y.name,to:t},notCovered:Ae,steps:Pe.map((Re)=>({id:Re.step.id,title:Re.step.title,state:Re.state,change:Re.step.change,reason:Re.reason}))},null,2));return}for(let Re of qs($e,Pe))console.log(Re);for(let Re of Ae)console.log(` not covered: ${Re}`);console.log(" Re-run with --apply to perform it.");return}let Se=await Gs($e,Pe,{log:(Ae)=>e(Ae),audit:(Ae)=>U.controlPlane.store.appendEvent({projectId:U.controlPlane.project.id,resourceId:Y.resourceId,type:`${Ae.operation}.${Ae.step}.${Ae.state}`,level:Ae.state==="failed"?"error":"info",payload:{target:Ae.target,renameTo:t,...Ae.error?{error:Ae.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Se},null,2));if(!Se.success){let Ae=Se.steps.find((Re)=>Re.state==="failed");throw Error(`${$e.operation} stopped at '${Ae?.title}': ${Ae?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function Qa(D){D.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await mi(async(A)=>{let _=t?[Mi(A,t)]:A.store.list(A.controlPlane.project.id),z=_.flatMap((U)=>Object.entries(U.capabilities).map(([Y,X])=>({server:U.name,provider:U.provider,action:Y,...X})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:z},null,2));else c(["Server","Provider","Action","Support","Explanation"],z.map((U)=>[U.server,U.provider,U.action,U.supported?"supported":"unsupported",U.reason??"—"]))})}catch(A){vn(A)}}),D.command("server:resize <name> <type>","Safely resize Hetzner compute with full host verification").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Execute the reviewed resize plan").option("--confirm <name>","Exact server name required for mutation").option("--upgrade-disk","Permanently expand the root disk to the target size",{default:!0}).option("--wait","Poll capacity without taking the server offline until placement is available").option("--poll-seconds <seconds>","Capacity retry interval",{default:"900"}).option("--max-wait-minutes <minutes>","Stop waiting after this many minutes; 0 waits indefinitely",{default:"0"}).option("--json","Print structured JSON").action(async(t,m,A)=>{try{await yp(t,m,A)}catch(_){vn(_)}}),D.command("server:optimize <name>","Reconcile and verify a production Hetzner host").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Apply the reviewed host optimization plan").option("--confirm <name>","Exact server name required for mutation").option("--json","Print structured JSON").action(async(t,m)=>{try{await vp(t,m)}catch(A){vn(A)}}),D.command("server:monitoring <name>","Read historical Hetzner CPU, RAM, swap, disk, and network metrics").option("--env <environment>","Deployment environment",{default:"production"}).option("--range <duration>","Historical window from 5m to 24h",{default:"3h"}).option("--step <seconds>","Hetzner provider sample interval",{default:"60"}).option("--json","Print structured JSON").action(async(t,m)=>{try{await gp(t,m)}catch(A){vn(A)}}),D.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await mi(async(m)=>{let A=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],A.map((_)=>[_.name,_.providerId??"—",`${_.provider} / ${_.region??"external"}`,`${_.status} / ${_.trustState}`,_.roles.join(","),`${_.capacity.cpu??0} / ${_.capacity.memoryBytes??0}`,_.heartbeatAt??"never"]))})}catch(m){vn(m)}}),D.command("server:create <name>","Enroll a provisioned or existing server").option("--provider <provider>","aws, hetzner, or ssh",{default:"ssh"}).option("--provider-id <id>","Stable provider identity").option("--endpoint <host>","SSH hostname or IP").option("--user <user>","Non-root SSH user",{default:"deploy"}).option("--credential-ref <ref>","Secret reference",{default:"secret://fleet/agent"}).option("--region <region>","Provider region").option("--roles <roles>","Comma-separated roles",{default:"application"}).option("--labels <labels>","Comma-separated key=value labels").action(async(t,m)=>{try{await mi(async(A)=>{let _=m.provider;if(!["aws","hetzner","ssh"].includes(_)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let z=A.service.enroll({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,provider:_,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((U)=>U.split("=")).filter((U)=>U[0]&&U[1]))});n(`Enrolled ${z.name} as ${z.id}; no remote mutation was performed.`)})}catch(A){vn(A)}}),D.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(t,m)=>{try{await mi(async(A)=>{let _=Mi(A,t);if(_=await A.service.test(_.id),_.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${_.pendingHostKey}; review it first.`);_=A.service.reviewHostKey(_.id,m.acceptHostKey)}let z=await A.service.validate(_.id);if(m.json)console.log(JSON.stringify(z.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(z.validation?.findings??[]).map((U)=>[U.severity,U.code,U.message,U.remediation??"—"]));if(!z.validation?.valid)process.exitCode=1})}catch(A){vn(A)}}),D.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await mi(async(A)=>{let _=A.service.bootstrap(Mi(A,t).id,!!m.apply);if(_.preview)c(["Step"],_.steps.map((z)=>[z]));else n(`Bootstrap queued: ${_.operation?.id}`)})}catch(A){vn(A)}}),D.command("server:rename <name> <new-name>","Rename a server in place, without recreating it").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Perform the reviewed rename plan").option("--json","Print structured JSON").action(async(t,m,A)=>{try{await bp(t,m,A)}catch(_){vn(_)}}),D.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await mi(async(A)=>n(A.service.drain(Mi(A,t).id,!!m.complete).status))}catch(A){vn(A)}}),D.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await mi(async(m)=>{m.service.uncordon(Mi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){vn(m)}}),D.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await mi(async(A)=>{A.service.archive(Mi(A,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(A){vn(A)}}),D.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await mi(async(m)=>{let A=Mi(m,t);if(A.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let _=Bun.spawn(["ssh","-p",String(A.sshPort),"-o","StrictHostKeyChecking=yes",`${A.sshUser}@${A.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),z=await _.exited;if(z)process.exitCode=z})}catch(m){vn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])D.command(t,m).action(async(...A)=>Rn(t.split(" ")[0],{target:String(A[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as vd,mkdirSync as wp,readFileSync as Sp,writeFileSync as Cp}from"node:fs";import{join as bd,resolve as $p}from"node:path";var Xa=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};async function kp(){try{return await De()}catch{return}}function Ap(D){if(D===void 0)return;let t=Number(D);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${D}'.`);return t}function wd(D,t,m){let A=D?.ssh?.hosts?.find((_)=>_.host===t);return new yr({hosts:t?[A??{host:t}]:D?.ssh?.hosts,user:m.user,port:Ap(m.port),privateKeyPath:m.key,hostKey:D?.ssh?.hostKey,sudo:D?.ssh?.sudo,profile:m.profile??D?.ssh?.profile,publicIp:D?.ssh?.publicIp,lan:D?.ssh?.lan})}var Sd=1073741824;function ec(D){D.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let A=await kp(),_=wd(A,t,m),z=t??_.targetHost(),U=await _.ensureHostKey(z),{facts:Y,findings:X}=await _.preflight(z);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:z,hostKeyFingerprint:U.fingerprint,facts:Y,findings:X},null,2));else{if(i(`Preflight ${z}`),U.pinnedNow)e(`Pinned host key ${U.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/Sd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/Sd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(rn(X)),hr(X))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(hr(X))process.exitCode=1}catch(A){Xa(A)}}),D.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await De(),A=t.env??"production";if(t.dryRun){let U=fr(m),[Y]=U.hosts;console.log(gr({config:m,environment:A,profile:U.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:U.lan}));return}let _=wd(m,void 0,{});i(`Adopt ${_.targetHost()}`);let z=await _.provisionComputeInfrastructure({config:m,environment:A});n(`${z.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${A}`)}catch(m){Xa(m)}}),D.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in to))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let A=await De(),_=t.env??"production",z=fr(A,{hosts:A.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),U=t.user??(A.ssh?.hosts?.[0]?.user??"pi"),Y=en(t.key??"~/.ssh/id_ed25519.pub");if(!vd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let X=Sp(Y,"utf8").trim(),ne;if(t.wifiSsid){let ke=t.wifiPassphraseEnv??"WIFI_PASSWORD",le=process.env[ke];if(!le)throw Error(`--wifi-ssid needs the passphrase in $${ke} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");ne={ssid:t.wifiSsid,passphrase:le,country:t.wifiCountry}}let re=gr({config:A,environment:_,profile:z.profile,sudoUser:U!=="root"?U:void 0,lan:z.lan}),ie=ro({hostname:t.hostname,user:U,publicKey:X,timezone:t.timezone,locale:t.locale,wifi:ne},re,{os:m}),ae=$p(t.out);wp(ae,{recursive:!0});let be=Object.keys(ie.files).filter((ke)=>vd(bd(ae,ke)));if(be.length>0&&!t.force)throw Error(`${be.join(", ")} already exist in ${ae}; pass --force to overwrite.`);for(let[ke,le]of Object.entries(ie.files))Cp(bd(ae,ke),le,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(ie.files).join(", ")} to ${ae}`),console.log(ie.instructions)}catch(m){Xa(m)}})}async function Rp(){let D=await De(),t=y(process.cwd(),D),m=new $n(t.store),A=new Ln(m,new xe(t.store));return{controlPlane:t,store:m,service:A}}async function fs(D){let t=await Rp();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Hs=(D)=>Object.fromEntries(String(D??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Cd=(D)=>Object.fromEntries(Object.entries(Hs(D)).map(([t,m])=>[t,Number(m)]));function tc(D){D.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>fs((m)=>{let A=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],A.map((_)=>[_.name,_.purpose,_.backend,`${_.region??"any"} / ${_.architecture??"any"}`,_.status,JSON.stringify(_.capacity),String(_.concurrency)]))})),D.command("pool:create <name>","Create a capacity pool").option("--purpose <purpose>","application, build, worker, monitoring, or backup",{default:"application"}).option("--backend <backend>","server, ecs, or asg",{default:"server"}).option("--capacity <values>","cpu=4,memoryBytes=8589934592,diskBytes=...").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Pool key=value labels").option("--selector <labels>","Required server labels").option("--max <count>","Maximum workloads",{default:"10"}).option("--concurrency <count>","Build concurrency",{default:"1"}).action(async(t,m)=>fs((A)=>{let{purpose:_,backend:z}=m;if(!["application","build","worker","monitoring","backup"].includes(_)||!["server","ecs","asg"].includes(z))throw Error("Unsupported pool purpose or backend.");let U=A.store.createPool({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,purpose:_,backend:z,region:m.region,architecture:m.arch,labels:Hs(m.labels),requiredServerLabels:Hs(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Cd(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${U.name} (${U.id}).`)})),D.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>fs((A)=>{let _=A.store.listPools(A.controlPlane.project.id).find((U)=>U.id===t||U.name===t),z=new xe(A.controlPlane.store).list(A.controlPlane.project.id).find((U)=>U.id===m||U.name===m);if(!_||!z)throw Error("Pool or server was not found.");A.store.addMember(_.id,z.id),n(`Attached ${z.name} to ${_.name}.`)})),D.command("placement:explain","Explain eligible and rejected placement targets").option("--purpose <purpose>","Workload purpose",{default:"application"}).option("--resources <values>","Requested resources").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Required pool labels").option("--json","Print structured JSON").action(async(t)=>fs((m)=>{let A=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Cd(t.resources),region:t.region,architecture:t.arch,labels:Hs(t.labels)});if(t.json)console.log(JSON.stringify(A,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],A.map((_)=>[_.poolName,_.serverId??"provider-managed",_.eligible?"yes":"no",JSON.stringify(_.available),`${_.score.fit.toFixed(2)} / ${_.score.spread} / ${_.score.cost}`,_.reasons.join("; ")||"eligible"]))})),D.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(t)=>fs((m)=>{let A=m.store.listPools(m.controlPlane.project.id).find((z)=>z.id===t||z.name===t);if(!A)throw Error("Pool was not found.");let _=m.service.drainPool(A.id);n(`Draining ${A.name}: moved ${_.moved.length}, blocked ${_.blocked.length} stateful placement(s).`)}))}async function Ip(){let D=await De(),t=y(process.cwd(),D),m=new Mn(t.store),A=new Un(m);return{controlPlane:t,store:m,service:A}}async function mo(D){let t=await Ip();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var gs=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error("Regional topology was not found.");return m},Pp=(D)=>D.split(",").map((t,m)=>{let[A,_="aws"]=t.split(":");return{region:String(A),provider:_,role:m===0?"primary":"secondary"}}),Dp=(D)=>{let t=new Set(["s3","dynamodb","secrets"]),m=D.split(",").map((_)=>_.trim()),A=m.find((_)=>!t.has(_));if(A)throw Error(`Unsupported replication kind: ${A}`);return m};function nc(D){D.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>mo((m)=>{let A=m.store.list(m.controlPlane.project.id).map((_)=>({topology:_,targets:m.store.targets(_.id),channels:m.store.channels(_.id),route:m.store.route(_.id),executions:m.store.executions(_.id)}));if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],A.map((_)=>[_.topology.name,_.topology.hostname,_.topology.activeRegion,_.topology.status,_.topology.revision??"—",`${_.channels.filter((z)=>z.status==="in_sync").length}/${_.channels.length} in sync`]))})),D.command("region:create <name>","Create a persistent multi-region topology").option("--hostname <hostname>","Traffic hostname").option("--regions <regions>","Comma-separated region[:provider], primary first").option("--replicate <kinds>","s3,dynamodb,secrets",{default:"s3,dynamodb,secrets"}).option("--max-lag <seconds>","Maximum failover lag",{default:"30"}).option("--cdn","Enable CloudFront edge state").option("--waf","Enable WAF edge state").action(async(t,m)=>mo((A)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let _=A.service.create({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,hostname:m.hostname,regions:Pp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Dp(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`Created ${_.name} (${_.id}); run region:rollout with an immutable manifest.`)})),D.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(t,m,A)=>mo((_)=>c(["Step"],_.service.plan(gs(_,t).id,m,A.target).map((z)=>[z])))),D.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,A)=>mo(async(_)=>{let z=A.manifest?await Bun.file(A.manifest).json():{},U=_.service.enqueue({topologyId:gs(_,t).id,kind:"rollout",revision:m,manifest:z});n(`Regional rollout queued: ${U.operation.id}`)})),D.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${_.operation.id}`)})),D.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"failback",targetRegion:m});n(`Failback queued: ${_.operation.id}`)})),D.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${_.operation.id}; replicated data remains retained.`)}))}var hs="0.16.50";async function Ep(){let D=await De(),t=y(process.cwd(),D),m=new Bn(t.store),A=new jn(m),_=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((z)=>new Vn(z,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:A,cleanup:_}}async function ki(D){let t=await Ep();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function rc(D){D.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>ki((m)=>{let A={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},_=[...A.manifests.map((z)=>["update",z.version,z.compatibility.compatible?"compatible":"blocked",z.compatibility.reasons.join("; ")||z.channel]),...A.campaigns.map((z)=>["upgrade",z.id,z.status,z.currentStage??z.fromVersion]),...A.cleanups.map((z)=>["cleanup",z.kind,z.status,`${z.candidates.length} items / ${z.estimatedBytes} bytes`]),...A.drills.map((z)=>["DR drill",z.scenario,z.status,z.isolatedTarget])];if(t.json)console.log(JSON.stringify(A,null,2));else c(["Area","Name / version","Status","Detail"],_)})),D.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>ki(async(A)=>{let _=A.store.addTrustedKey({organizationId:A.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${_.name}: ${_.fingerprint}`)})),D.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,A)=>ki(async(_)=>{let z=await Bun.file(t).json(),U=(await Bun.file(m).text()).trim(),Y=_.store.importManifest({organizationId:_.controlPlane.organization.id,keyId:A,document:z,signature:U,current:{schemaVersion:_.controlPlane.store.health().schemaVersion,currentVersion:hs,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.compatibility.reasons.join("; ")}`)})),D.command("maintenance:window <name> <schedule>","Create an approved maintenance window").option("--timezone <timezone>","IANA timezone",{default:"UTC"}).option("--minutes <minutes>","Duration",{default:"60"}).action(async(t,m,A)=>ki((_)=>{let z=_.store.createWindow({projectId:_.controlPlane.project.id,name:t,schedule:m,timezone:A.timezone,durationMinutes:Number(A.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${z.name} (${z.id}).`)})),D.command("platform:upgrade <manifest> <backup>","Plan and queue a signed staged platform update").option("--strategy <strategy>","canary or rolling",{default:"canary"}).option("--batch <count>","Rolling batch size",{default:"1"}).action(async(t,m,A)=>ki((_)=>{let z=new xe(_.controlPlane.store).list(_.controlPlane.project.id).filter((X)=>X.status==="ready").map((X)=>({serverId:X.id,target:X.name,previousVersion:X.bootstrapVersion??hs}));if(!z.length)z.push({target:"control-plane",previousVersion:hs});let U=_.store.createCampaign({projectId:_.controlPlane.project.id,manifestId:t,fromVersion:hs,strategy:A.strategy==="rolling"?"rolling":"canary",batchSize:Number(A.batch),healthGate:{kind:"platform"},backupId:m,targets:z}),Y=_.service.enqueueCampaign(U.id);n(`Staged upgrade queued: ${Y.operation.id}`)})),D.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(t,m)=>ki(async(A)=>{let _=await A.service.previewCleanup({projectId:A.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},A.cleanup);c(["ID","Candidate","Bytes"],_.candidates.map((z)=>[z.id,z.label,String(z.bytes)])),e(`Apply with: cloud cleanup:apply ${_.id} --confirm "DELETE ${_.candidates.length} ${_.kind}"`)})),D.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(t,m)=>ki((A)=>{let _=A.service.enqueueCleanup(t,String(m.confirm??""));n(`Cleanup queued: ${_.operation.id}`)})),D.command("dr:plan <scenario> <target>","Plan an isolated disaster-recovery drill").option("--rpo <minutes>","RPO objective",{default:"60"}).option("--rto <minutes>","RTO objective",{default:"30"}).option("--recovery-point <id>","Recovery point").option("--topology <id>","Regional topology").action(async(t,m,A)=>ki((_)=>{let z=_.store.createDrill({projectId:_.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(A.rpo),expectedRtoMinutes:Number(A.rto),recoveryPointId:A.recoveryPoint,topologyId:A.topology});n(`Planned isolated drill ${z.id}.`)})),D.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>ki((m)=>{let A=m.service.enqueueDrill(t);n(`DR drill queued: ${A.operation.id}`)}))}async function ic(){try{return(await De()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function oc(D){D.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await ic(),A=new P(m);try{let{Functions:_=[]}=await A.listFunctions({MaxItems:50});if(!_.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],_.map((z)=>[z.FunctionName??"-",z.Runtime??"-",z.MemorySize?`${z.MemorySize} MB`:"-",z.Timeout?`${z.Timeout}s`:"-",z.LastModified??"-"]))}catch(_){r(`Failed to list functions: ${_.message}`),process.exitCode=1}}),D.command("function:invoke <name>","Invoke a Lambda function").option("--payload <json>","Event payload as JSON",{default:"{}"}).option("--async","Fire-and-forget (Event invocation)").option("--region <region>","AWS region").action(async(t,m)=>{i(`Invoking ${t}`);let A=m?.region||await ic(),_=new P(A),z=new s("Invoking function...");z.start();try{let U=await _.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(U.FunctionError){if(z.fail(`Function returned an error (${U.FunctionError})`),U.Payload)e(U.Payload);process.exitCode=1;return}if(z.succeed(`Invoked (status ${U.StatusCode})`),U.Payload)e(`
318
+ `)}async function pp(){let D=await De(),t=y(process.cwd(),D),m=new xe(t.store),A=new On(m,[new st("aws"),new st("hetzner"),new st("ssh")]);return{controlPlane:t,store:m,service:A}}async function mi(D){let t=await pp();try{return await D(t)}finally{t.controlPlane.store.close()}}var Mi=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},vn=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};function Za(D,t){let m=Number.parseInt(D??"",10);return Number.isFinite(m)&&m>=0?m:t}function fp(D="3h"){let t=D.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ts(D,t="%"){return D==null?"unavailable":`${D.toFixed(1)}${t}`}async function gp(D,t){let m=await De();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await ge(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to read ${D}: project state is pinned to ${z.serverName}.`);let U=ur(m),Y=new Je({apiToken:pr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=new Date,ie=new Date(re.getTime()-fp(t.range)),ae=Math.min(3600,Math.max(60,Za(t.step,60))),be=await fd({client:Y,serverId:X.id,cores:Math.max(1,Number(X.server_type.cores)||1),from:ie,to:re,step:ae,remote:{host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:X.name,result:be},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[X.name,`${be.from} to ${be.to}`,`${ts(be.summary.cpuAveragePercent)} / ${ts(be.summary.cpuPeakPercent)}`,`${ts(be.summary.memoryAveragePercent)} / ${ts(be.summary.memoryPeakPercent)}`,be.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(be.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ts(be.summary.swapPeakPercent)]])}function yd(D){let t=D.targetType.prices?.find((m)=>m.location===D.location);return{serverId:D.serverId,serverName:D.serverName,location:D.location,from:D.currentType.name,to:D.targetType.name,capacityAvailable:D.capacityAvailable,alreadyComplete:D.alreadyComplete,upgradeDisk:D.upgradeDisk,target:{cores:D.targetType.cores,memoryGb:D.targetType.memory,diskGb:D.targetType.disk,architecture:D.targetType.architecture,cpuType:D.targetType.cpu_type},price:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function hp(D){let t=yd(D);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function yp(D,t,m){let A=await De();if(A.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let _=m.env??process.env.CLOUD_ENV??"production",z=T(A,_),U=await ge(z),Y=ur(A),X=new Je({apiToken:pr(Y.apiToken,A)}),re=U&&(D===U.serverName||D===String(U.serverId)||D===U.stackName)?await X.getServer(U.serverId):(await X.listServers()).find((Ne)=>Ne.name===D||String(Ne.id)===D);if(!re)throw Error(`Hetzner server ${D} was not found.`);if(U?.serverId&&U.serverId!==re.id)throw Error(`Refusing to resize ${D}: project state is pinned to server ${U.serverId}.`);let ie=pt(t),ae=m.upgradeDisk!==!1,be=await ui(X,re.id,ie,ae);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:yd(be)},null,2));else hp(be);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${re.name} to execute.`);return}if(m.confirm!==re.name)throw Error(`Resize requires --confirm ${re.name}.`);let ke=U?.publicIp??re.public_net.ipv4?.ip;if(!ke)throw Error(`Server ${re.name} has no public IPv4 address for verification.`);let le={host:ke,user:U?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},$e=await ps(z),Pe=new Date().toISOString(),Se={schemaVersion:1,operationId:$e?.targetType===ie&&$e.serverId===re.id?$e.operationId:crypto.randomUUID(),stackName:z,serverId:re.id,serverName:re.name,sourceType:be.currentType.name,targetType:ie,upgradeDisk:ae,phase:"planning",status:"running",attempts:$e?.targetType===ie?$e.attempts:0,startedAt:$e?.targetType===ie?$e.startedAt:Pe,updatedAt:Pe,manifest:$e?.targetType===ie?$e.manifest:void 0};await gt(Se);let Ae=Za(m.pollSeconds,900)*1000,Re=Za(m.maxWaitMinutes,0)*60000,ze=Date.now();for(;;){let Ne=await ui(X,re.id,ie,ae);if(!Ne.capacityAvailable&&!Ne.alreadyComplete){if(Se={...Se,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await gt(Se),!m.wait){if(!m.json)e(`${ie} has no capacity in ${Ne.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Re>0&&Date.now()-ze>=Re)throw Error(`Timed out waiting for ${ie} capacity in ${Ne.location}.`);if(!m.json)e(`Waiting ${Math.round(Ae/1000)} seconds for ${ie} capacity...`);await Bun.sleep(Ae);continue}let je=await ms(z);try{let Ue=await(async()=>{try{return Se={...Se,status:"running",attempts:Se.attempts+1,updatedAt:new Date().toISOString()},await gt(Se),await ss({client:X,serverId:re.id,targetType:ie,upgradeDisk:ae,resumeFromOff:Se.phase==="shutting-down"||Se.phase==="resizing"||Se.phase==="powering-on"||Se.phase==="verifying",manifest:Se.manifest,hooks:{preflight:async()=>{let Ct=await as(le);return Se={...Se,manifest:Ct,updatedAt:new Date().toISOString()},await gt(Se),Ct},afterBoot:async(Ct,At,rt,kt)=>cs(le,At,rt,kt),onPhase:async(Ct,At)=>{if(Se={...Se,phase:Ct,status:Ct==="waiting-capacity"?"waiting-capacity":Ct==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await gt(Se),!m.json)e(`${Ct}${At?` ${JSON.stringify(At)}`:""}`)}}})}finally{await je()}})();if(Se={...Se,status:Ue.status==="completed"||Ue.status==="already-complete"?"completed":Ue.status==="recovered"?"recovered":"waiting-capacity",lastError:Ue.status==="recovered"?Ue.error:void 0,updatedAt:new Date().toISOString()},await gt(Se),m.json)console.log(JSON.stringify({schemaVersion:1,result:Ue},null,2));else if(Ue.status==="completed"||Ue.status==="already-complete")n(`${re.name} is on ${ie} and passed full post-boot verification.`);else if(Ue.status==="recovered"&&Ue.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(Ae/1000)} seconds before retry.`),await Bun.sleep(Ae);continue}else if(Ue.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${Ue.error}`);return}catch(Ue){throw Se={...Se,status:"failed",lastError:Ue instanceof Error?Ue.message:String(Ue),updatedAt:new Date().toISOString()},await gt(Se),Ue}}}async function vp(D,t){let m=await De();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await ge(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to optimize ${D}: project state is pinned to ${z.serverName}.`);let U=ur(m),Y=new Je({apiToken:pr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=no(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:X.name,plan:re},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[X.name,re.firewallPorts.join(","),re.monitoring?"on":"off",re.autoUpdates?"on":"off",`${re.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${X.name} to execute.`);return}if(t.confirm!==X.name)throw Error(`Optimization requires --confirm ${X.name}.`);let ie={host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15},ae=await nn(ie),be=ae.routeProbes.filter((rt)=>!rt.ok),ke=m.infrastructure?.compute,le=Z(ke)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,$e=ae.failedUnits.filter((rt)=>!le.has(rt));if($e.length>0)throw Error(`Preflight found failed services: ${$e.join(", ")}`);if(be.length>0)throw Error(`Preflight found unhealthy routes: ${be.map((rt)=>rt.domain).join(", ")}`);let Pe=Z(ke)?[]:Object.values(m.sites??{}).flatMap((rt)=>typeof rt?.port==="number"&&![80,443].includes(rt.port)?[rt.port]:[]),Se=tn({allowSsh:ke?.allowSsh!==!1,sitePorts:Pe,allowedPorts:ke?.firewall?.allowedPorts}),Ae=(z.firewallId?(await Y.listFirewalls()).find((rt)=>rt.id===z.firewallId):void 0)??(await Y.listFirewalls()).find((rt)=>rt.name===`${m.project.slug}-${A}-app-fw`);if(!Ae)throw Error(`Managed firewall for ${X.name} was not found.`);let Re=await Y.setFirewallRules(Ae.id,Se);await Promise.all(Re.map((rt)=>Y.waitForAction(rt.id))),await ls(m,ie);let[ze,Ne]=await Promise.all([nn(ie),ds(ie)]),je=us(re,Ne),Ue=gc(ae,ze),Ct=ze.routeProbes.filter((rt)=>!rt.ok);if(Ue.stoppedServices.length>0)je.push(`services stopped: ${Ue.stoppedServices.join(", ")}`);if(Ue.changedRouteFragments.length>0)je.push(`route fragments changed: ${Ue.changedRouteFragments.join(", ")}`);if(Ue.missingRouteIds.length>0)je.push(`routes disappeared: ${Ue.missingRouteIds.join(", ")}`);if(Ue.changedReleaseLinks.length>0)je.push(`release links changed: ${Ue.changedReleaseLinks.join(", ")}`);if(Ue.missingData.length>0)je.push(`databases or volumes disappeared: ${Ue.missingData.join(", ")}`);if(Ct.length>0)je.push(`unhealthy routes: ${Ct.map((rt)=>rt.domain).join(", ")}`);if(je.length>0)throw Error(`Host optimization verification failed: ${je.join("; ")}`);let At={serverId:X.id,serverName:X.name,services:ze.runningServices.length,routes:ze.routeIds.length,healthyDomains:ze.routeProbes.length,releaseLinks:ze.releaseLinks.length,databasesAndVolumes:ze.dataCatalog.length,report:Ne};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:At},null,2));else n(`${X.name} passed full host, rpx route, service, release, and data verification.`)}async function bp(D,t,m){let A=await De(),_=m.env??"production",z=T(A,_);await mi(async(U)=>{let Y=Mi(U,D),X=U.store.list(U.controlPlane.project.id,!0),ne=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let Ae=ur(A);return new Je({apiToken:pr(Ae.apiToken,A)})}catch{return null}})():null,re=Y.providerId?Number(Y.providerId):Number.NaN,ie=await ge(z),ae=ie!=null&&ie.serverId===re,be=new zr,ke=Y.trustState==="pinned",le={takenNames:async()=>{let Ae=X.map((Re)=>Re.name);if(ne)Ae.push(...(await ne.listServers()).map((Re)=>Re.name));return Ae},inventoryName:()=>U.store.get(Y.id)?.name??Y.name,renameInventory:(Ae)=>{U.store.update(Y.id,{name:Ae})},...ne&&Number.isFinite(re)?{providerName:async()=>(await ne.getServer(re)).name,renameProvider:async(Ae)=>{await ne.renameServer(re,Ae)}}:{},...ae?{stateName:async()=>(await ge(z))?.serverName,writeStateName:async(Ae)=>{let Re=await ge(z);if(Re)await mt(z,{...Re,serverName:Ae})}}:{},...ke?{remoteHostname:async()=>{let Ae=await be.exec(Y,"hostname");return Ae.code===0?Ae.stdout.trim():void 0},setRemoteHostname:async(Ae)=>{let Re=await be.exec(Y,hd(Ae));if(Re.code!==0)throw Error(Re.stderr.trim()||`hostname exited ${Re.code}`)}}:{}},$e=await gd(Y.name,t,le),Pe=await Us($e);if(!m.apply){let Ae=[ne?"":"provider record (no provider id or no API token)",ae?"":"local state pin (none points at this server)",ke?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:$e.operation,target:$e.target,rename:{from:Y.name,to:t},notCovered:Ae,steps:Pe.map((Re)=>({id:Re.step.id,title:Re.step.title,state:Re.state,change:Re.step.change,reason:Re.reason}))},null,2));return}for(let Re of qs($e,Pe))console.log(Re);for(let Re of Ae)console.log(` not covered: ${Re}`);console.log(" Re-run with --apply to perform it.");return}let Se=await Gs($e,Pe,{log:(Ae)=>e(Ae),audit:(Ae)=>U.controlPlane.store.appendEvent({projectId:U.controlPlane.project.id,resourceId:Y.resourceId,type:`${Ae.operation}.${Ae.step}.${Ae.state}`,level:Ae.state==="failed"?"error":"info",payload:{target:Ae.target,renameTo:t,...Ae.error?{error:Ae.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Se},null,2));if(!Se.success){let Ae=Se.steps.find((Re)=>Re.state==="failed");throw Error(`${$e.operation} stopped at '${Ae?.title}': ${Ae?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function Qa(D){D.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await mi(async(A)=>{let _=t?[Mi(A,t)]:A.store.list(A.controlPlane.project.id),z=_.flatMap((U)=>Object.entries(U.capabilities).map(([Y,X])=>({server:U.name,provider:U.provider,action:Y,...X})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:z},null,2));else c(["Server","Provider","Action","Support","Explanation"],z.map((U)=>[U.server,U.provider,U.action,U.supported?"supported":"unsupported",U.reason??"—"]))})}catch(A){vn(A)}}),D.command("server:resize <name> <type>","Safely resize Hetzner compute with full host verification").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Execute the reviewed resize plan").option("--confirm <name>","Exact server name required for mutation").option("--upgrade-disk","Permanently expand the root disk to the target size",{default:!0}).option("--wait","Poll capacity without taking the server offline until placement is available").option("--poll-seconds <seconds>","Capacity retry interval",{default:"900"}).option("--max-wait-minutes <minutes>","Stop waiting after this many minutes; 0 waits indefinitely",{default:"0"}).option("--json","Print structured JSON").action(async(t,m,A)=>{try{await yp(t,m,A)}catch(_){vn(_)}}),D.command("server:optimize <name>","Reconcile and verify a production Hetzner host").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Apply the reviewed host optimization plan").option("--confirm <name>","Exact server name required for mutation").option("--json","Print structured JSON").action(async(t,m)=>{try{await vp(t,m)}catch(A){vn(A)}}),D.command("server:monitoring <name>","Read historical Hetzner CPU, RAM, swap, disk, and network metrics").option("--env <environment>","Deployment environment",{default:"production"}).option("--range <duration>","Historical window from 5m to 24h",{default:"3h"}).option("--step <seconds>","Hetzner provider sample interval",{default:"60"}).option("--json","Print structured JSON").action(async(t,m)=>{try{await gp(t,m)}catch(A){vn(A)}}),D.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await mi(async(m)=>{let A=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],A.map((_)=>[_.name,_.providerId??"—",`${_.provider} / ${_.region??"external"}`,`${_.status} / ${_.trustState}`,_.roles.join(","),`${_.capacity.cpu??0} / ${_.capacity.memoryBytes??0}`,_.heartbeatAt??"never"]))})}catch(m){vn(m)}}),D.command("server:create <name>","Enroll a provisioned or existing server").option("--provider <provider>","aws, hetzner, or ssh",{default:"ssh"}).option("--provider-id <id>","Stable provider identity").option("--endpoint <host>","SSH hostname or IP").option("--user <user>","Non-root SSH user",{default:"deploy"}).option("--credential-ref <ref>","Secret reference",{default:"secret://fleet/agent"}).option("--region <region>","Provider region").option("--roles <roles>","Comma-separated roles",{default:"application"}).option("--labels <labels>","Comma-separated key=value labels").action(async(t,m)=>{try{await mi(async(A)=>{let _=m.provider;if(!["aws","hetzner","ssh"].includes(_)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let z=A.service.enroll({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,provider:_,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((U)=>U.split("=")).filter((U)=>U[0]&&U[1]))});n(`Enrolled ${z.name} as ${z.id}; no remote mutation was performed.`)})}catch(A){vn(A)}}),D.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(t,m)=>{try{await mi(async(A)=>{let _=Mi(A,t);if(_=await A.service.test(_.id),_.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${_.pendingHostKey}; review it first.`);_=A.service.reviewHostKey(_.id,m.acceptHostKey)}let z=await A.service.validate(_.id);if(m.json)console.log(JSON.stringify(z.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(z.validation?.findings??[]).map((U)=>[U.severity,U.code,U.message,U.remediation??"—"]));if(!z.validation?.valid)process.exitCode=1})}catch(A){vn(A)}}),D.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await mi(async(A)=>{let _=A.service.bootstrap(Mi(A,t).id,!!m.apply);if(_.preview)c(["Step"],_.steps.map((z)=>[z]));else n(`Bootstrap queued: ${_.operation?.id}`)})}catch(A){vn(A)}}),D.command("server:rename <name> <new-name>","Rename a server in place, without recreating it").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Perform the reviewed rename plan").option("--json","Print structured JSON").action(async(t,m,A)=>{try{await bp(t,m,A)}catch(_){vn(_)}}),D.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await mi(async(A)=>n(A.service.drain(Mi(A,t).id,!!m.complete).status))}catch(A){vn(A)}}),D.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await mi(async(m)=>{m.service.uncordon(Mi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){vn(m)}}),D.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await mi(async(A)=>{A.service.archive(Mi(A,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(A){vn(A)}}),D.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await mi(async(m)=>{let A=Mi(m,t);if(A.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let _=Bun.spawn(["ssh","-p",String(A.sshPort),"-o","StrictHostKeyChecking=yes",`${A.sshUser}@${A.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),z=await _.exited;if(z)process.exitCode=z})}catch(m){vn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])D.command(t,m).action(async(...A)=>Rn(t.split(" ")[0],{target:String(A[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as vd,mkdirSync as wp,readFileSync as Sp,writeFileSync as Cp}from"node:fs";import{join as bd,resolve as $p}from"node:path";var Xa=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};async function kp(){try{return await De()}catch{return}}function Ap(D){if(D===void 0)return;let t=Number(D);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${D}'.`);return t}function wd(D,t,m){let A=D?.ssh?.hosts?.find((_)=>_.host===t);return new yr({hosts:t?[A??{host:t}]:D?.ssh?.hosts,user:m.user,port:Ap(m.port),privateKeyPath:m.key,hostKey:D?.ssh?.hostKey,sudo:D?.ssh?.sudo,profile:m.profile??D?.ssh?.profile,publicIp:D?.ssh?.publicIp,lan:D?.ssh?.lan})}var Sd=1073741824;function ec(D){D.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let A=await kp(),_=wd(A,t,m),z=t??_.targetHost(),U=await _.ensureHostKey(z),{facts:Y,findings:X}=await _.preflight(z);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:z,hostKeyFingerprint:U.fingerprint,facts:Y,findings:X},null,2));else{if(i(`Preflight ${z}`),U.pinnedNow)e(`Pinned host key ${U.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/Sd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/Sd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(rn(X)),hr(X))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(hr(X))process.exitCode=1}catch(A){Xa(A)}}),D.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await De(),A=t.env??"production";if(t.dryRun){let U=fr(m),[Y]=U.hosts;console.log(gr({config:m,environment:A,profile:U.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:U.lan}));return}let _=wd(m,void 0,{});i(`Adopt ${_.targetHost()}`);let z=await _.provisionComputeInfrastructure({config:m,environment:A});n(`${z.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${A}`)}catch(m){Xa(m)}}),D.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in to))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let A=await De(),_=t.env??"production",z=fr(A,{hosts:A.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),U=t.user??(A.ssh?.hosts?.[0]?.user??"pi"),Y=en(t.key??"~/.ssh/id_ed25519.pub");if(!vd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let X=Sp(Y,"utf8").trim(),ne;if(t.wifiSsid){let ke=t.wifiPassphraseEnv??"WIFI_PASSWORD",le=process.env[ke];if(!le)throw Error(`--wifi-ssid needs the passphrase in $${ke} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");ne={ssid:t.wifiSsid,passphrase:le,country:t.wifiCountry}}let re=gr({config:A,environment:_,profile:z.profile,sudoUser:U!=="root"?U:void 0,lan:z.lan}),ie=ro({hostname:t.hostname,user:U,publicKey:X,timezone:t.timezone,locale:t.locale,wifi:ne},re,{os:m}),ae=$p(t.out);wp(ae,{recursive:!0});let be=Object.keys(ie.files).filter((ke)=>vd(bd(ae,ke)));if(be.length>0&&!t.force)throw Error(`${be.join(", ")} already exist in ${ae}; pass --force to overwrite.`);for(let[ke,le]of Object.entries(ie.files))Cp(bd(ae,ke),le,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(ie.files).join(", ")} to ${ae}`),console.log(ie.instructions)}catch(m){Xa(m)}})}async function Rp(){let D=await De(),t=y(process.cwd(),D),m=new $n(t.store),A=new Ln(m,new xe(t.store));return{controlPlane:t,store:m,service:A}}async function fs(D){let t=await Rp();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Hs=(D)=>Object.fromEntries(String(D??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Cd=(D)=>Object.fromEntries(Object.entries(Hs(D)).map(([t,m])=>[t,Number(m)]));function tc(D){D.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>fs((m)=>{let A=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],A.map((_)=>[_.name,_.purpose,_.backend,`${_.region??"any"} / ${_.architecture??"any"}`,_.status,JSON.stringify(_.capacity),String(_.concurrency)]))})),D.command("pool:create <name>","Create a capacity pool").option("--purpose <purpose>","application, build, worker, monitoring, or backup",{default:"application"}).option("--backend <backend>","server, ecs, or asg",{default:"server"}).option("--capacity <values>","cpu=4,memoryBytes=8589934592,diskBytes=...").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Pool key=value labels").option("--selector <labels>","Required server labels").option("--max <count>","Maximum workloads",{default:"10"}).option("--concurrency <count>","Build concurrency",{default:"1"}).action(async(t,m)=>fs((A)=>{let{purpose:_,backend:z}=m;if(!["application","build","worker","monitoring","backup"].includes(_)||!["server","ecs","asg"].includes(z))throw Error("Unsupported pool purpose or backend.");let U=A.store.createPool({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,purpose:_,backend:z,region:m.region,architecture:m.arch,labels:Hs(m.labels),requiredServerLabels:Hs(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Cd(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${U.name} (${U.id}).`)})),D.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>fs((A)=>{let _=A.store.listPools(A.controlPlane.project.id).find((U)=>U.id===t||U.name===t),z=new xe(A.controlPlane.store).list(A.controlPlane.project.id).find((U)=>U.id===m||U.name===m);if(!_||!z)throw Error("Pool or server was not found.");A.store.addMember(_.id,z.id),n(`Attached ${z.name} to ${_.name}.`)})),D.command("placement:explain","Explain eligible and rejected placement targets").option("--purpose <purpose>","Workload purpose",{default:"application"}).option("--resources <values>","Requested resources").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Required pool labels").option("--json","Print structured JSON").action(async(t)=>fs((m)=>{let A=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Cd(t.resources),region:t.region,architecture:t.arch,labels:Hs(t.labels)});if(t.json)console.log(JSON.stringify(A,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],A.map((_)=>[_.poolName,_.serverId??"provider-managed",_.eligible?"yes":"no",JSON.stringify(_.available),`${_.score.fit.toFixed(2)} / ${_.score.spread} / ${_.score.cost}`,_.reasons.join("; ")||"eligible"]))})),D.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(t)=>fs((m)=>{let A=m.store.listPools(m.controlPlane.project.id).find((z)=>z.id===t||z.name===t);if(!A)throw Error("Pool was not found.");let _=m.service.drainPool(A.id);n(`Draining ${A.name}: moved ${_.moved.length}, blocked ${_.blocked.length} stateful placement(s).`)}))}async function Ip(){let D=await De(),t=y(process.cwd(),D),m=new Mn(t.store),A=new Un(m);return{controlPlane:t,store:m,service:A}}async function mo(D){let t=await Ip();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var gs=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error("Regional topology was not found.");return m},Pp=(D)=>D.split(",").map((t,m)=>{let[A,_="aws"]=t.split(":");return{region:String(A),provider:_,role:m===0?"primary":"secondary"}}),Dp=(D)=>{let t=new Set(["s3","dynamodb","secrets"]),m=D.split(",").map((_)=>_.trim()),A=m.find((_)=>!t.has(_));if(A)throw Error(`Unsupported replication kind: ${A}`);return m};function nc(D){D.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>mo((m)=>{let A=m.store.list(m.controlPlane.project.id).map((_)=>({topology:_,targets:m.store.targets(_.id),channels:m.store.channels(_.id),route:m.store.route(_.id),executions:m.store.executions(_.id)}));if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],A.map((_)=>[_.topology.name,_.topology.hostname,_.topology.activeRegion,_.topology.status,_.topology.revision??"—",`${_.channels.filter((z)=>z.status==="in_sync").length}/${_.channels.length} in sync`]))})),D.command("region:create <name>","Create a persistent multi-region topology").option("--hostname <hostname>","Traffic hostname").option("--regions <regions>","Comma-separated region[:provider], primary first").option("--replicate <kinds>","s3,dynamodb,secrets",{default:"s3,dynamodb,secrets"}).option("--max-lag <seconds>","Maximum failover lag",{default:"30"}).option("--cdn","Enable CloudFront edge state").option("--waf","Enable WAF edge state").action(async(t,m)=>mo((A)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let _=A.service.create({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,hostname:m.hostname,regions:Pp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Dp(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`Created ${_.name} (${_.id}); run region:rollout with an immutable manifest.`)})),D.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(t,m,A)=>mo((_)=>c(["Step"],_.service.plan(gs(_,t).id,m,A.target).map((z)=>[z])))),D.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,A)=>mo(async(_)=>{let z=A.manifest?await Bun.file(A.manifest).json():{},U=_.service.enqueue({topologyId:gs(_,t).id,kind:"rollout",revision:m,manifest:z});n(`Regional rollout queued: ${U.operation.id}`)})),D.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${_.operation.id}`)})),D.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"failback",targetRegion:m});n(`Failback queued: ${_.operation.id}`)})),D.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(t,m)=>mo((A)=>{let _=A.service.enqueue({topologyId:gs(A,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${_.operation.id}; replicated data remains retained.`)}))}var hs="0.16.51";async function Ep(){let D=await De(),t=y(process.cwd(),D),m=new Bn(t.store),A=new jn(m),_=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((z)=>new Vn(z,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:A,cleanup:_}}async function ki(D){let t=await Ep();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function rc(D){D.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>ki((m)=>{let A={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},_=[...A.manifests.map((z)=>["update",z.version,z.compatibility.compatible?"compatible":"blocked",z.compatibility.reasons.join("; ")||z.channel]),...A.campaigns.map((z)=>["upgrade",z.id,z.status,z.currentStage??z.fromVersion]),...A.cleanups.map((z)=>["cleanup",z.kind,z.status,`${z.candidates.length} items / ${z.estimatedBytes} bytes`]),...A.drills.map((z)=>["DR drill",z.scenario,z.status,z.isolatedTarget])];if(t.json)console.log(JSON.stringify(A,null,2));else c(["Area","Name / version","Status","Detail"],_)})),D.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>ki(async(A)=>{let _=A.store.addTrustedKey({organizationId:A.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${_.name}: ${_.fingerprint}`)})),D.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,A)=>ki(async(_)=>{let z=await Bun.file(t).json(),U=(await Bun.file(m).text()).trim(),Y=_.store.importManifest({organizationId:_.controlPlane.organization.id,keyId:A,document:z,signature:U,current:{schemaVersion:_.controlPlane.store.health().schemaVersion,currentVersion:hs,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.compatibility.reasons.join("; ")}`)})),D.command("maintenance:window <name> <schedule>","Create an approved maintenance window").option("--timezone <timezone>","IANA timezone",{default:"UTC"}).option("--minutes <minutes>","Duration",{default:"60"}).action(async(t,m,A)=>ki((_)=>{let z=_.store.createWindow({projectId:_.controlPlane.project.id,name:t,schedule:m,timezone:A.timezone,durationMinutes:Number(A.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${z.name} (${z.id}).`)})),D.command("platform:upgrade <manifest> <backup>","Plan and queue a signed staged platform update").option("--strategy <strategy>","canary or rolling",{default:"canary"}).option("--batch <count>","Rolling batch size",{default:"1"}).action(async(t,m,A)=>ki((_)=>{let z=new xe(_.controlPlane.store).list(_.controlPlane.project.id).filter((X)=>X.status==="ready").map((X)=>({serverId:X.id,target:X.name,previousVersion:X.bootstrapVersion??hs}));if(!z.length)z.push({target:"control-plane",previousVersion:hs});let U=_.store.createCampaign({projectId:_.controlPlane.project.id,manifestId:t,fromVersion:hs,strategy:A.strategy==="rolling"?"rolling":"canary",batchSize:Number(A.batch),healthGate:{kind:"platform"},backupId:m,targets:z}),Y=_.service.enqueueCampaign(U.id);n(`Staged upgrade queued: ${Y.operation.id}`)})),D.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(t,m)=>ki(async(A)=>{let _=await A.service.previewCleanup({projectId:A.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},A.cleanup);c(["ID","Candidate","Bytes"],_.candidates.map((z)=>[z.id,z.label,String(z.bytes)])),e(`Apply with: cloud cleanup:apply ${_.id} --confirm "DELETE ${_.candidates.length} ${_.kind}"`)})),D.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(t,m)=>ki((A)=>{let _=A.service.enqueueCleanup(t,String(m.confirm??""));n(`Cleanup queued: ${_.operation.id}`)})),D.command("dr:plan <scenario> <target>","Plan an isolated disaster-recovery drill").option("--rpo <minutes>","RPO objective",{default:"60"}).option("--rto <minutes>","RTO objective",{default:"30"}).option("--recovery-point <id>","Recovery point").option("--topology <id>","Regional topology").action(async(t,m,A)=>ki((_)=>{let z=_.store.createDrill({projectId:_.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(A.rpo),expectedRtoMinutes:Number(A.rto),recoveryPointId:A.recoveryPoint,topologyId:A.topology});n(`Planned isolated drill ${z.id}.`)})),D.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>ki((m)=>{let A=m.service.enqueueDrill(t);n(`DR drill queued: ${A.operation.id}`)}))}async function ic(){try{return(await De()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function oc(D){D.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await ic(),A=new P(m);try{let{Functions:_=[]}=await A.listFunctions({MaxItems:50});if(!_.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],_.map((z)=>[z.FunctionName??"-",z.Runtime??"-",z.MemorySize?`${z.MemorySize} MB`:"-",z.Timeout?`${z.Timeout}s`:"-",z.LastModified??"-"]))}catch(_){r(`Failed to list functions: ${_.message}`),process.exitCode=1}}),D.command("function:invoke <name>","Invoke a Lambda function").option("--payload <json>","Event payload as JSON",{default:"{}"}).option("--async","Fire-and-forget (Event invocation)").option("--region <region>","AWS region").action(async(t,m)=>{i(`Invoking ${t}`);let A=m?.region||await ic(),_=new P(A),z=new s("Invoking function...");z.start();try{let U=await _.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(U.FunctionError){if(z.fail(`Function returned an error (${U.FunctionError})`),U.Payload)e(U.Payload);process.exitCode=1;return}if(z.succeed(`Invoked (status ${U.StatusCode})`),U.Payload)e(`
319
319
  Response:`),e(U.Payload);if(U.LogResult)e(`
320
320
  Logs:`),e(Buffer.from(U.LogResult,"base64").toString("utf-8"))}catch(U){z.fail(`Invocation failed: ${U.message}`),process.exitCode=1}}),D.command("function:logs <name>","View recent function logs").option("--tail","Continuously stream new log events").option("--filter <pattern>","CloudWatch filter pattern").option("--since <minutes>","Look back this many minutes",{default:"15"}).option("--region <region>","AWS region").action(async(t,m)=>{i(`Logs for ${t}`);let A=m?.region||await ic(),_=new se(A),z=t.startsWith("/aws/lambda/")?t:`/aws/lambda/${t}`,U=Number(m?.since??15),Y=(X)=>{for(let ne of X){let re=ne.timestamp?new Date(ne.timestamp).toISOString():"";e(`${re} ${(ne.message??"").trimEnd()}`)}};try{let X=Date.now()-U*60000,{events:ne=[]}=await _.filterLogEvents({logGroupName:z,startTime:X,filterPattern:m?.filter,limit:200});if(Y(ne),ne.length)X=(ne[ne.length-1].timestamp??X)+1;if(m?.tail){e(`
321
321
  (streaming — Ctrl+C to stop)`);for(;;){await new Promise((ie)=>setTimeout(ie,3000));let{events:re=[]}=await _.filterLogEvents({logGroupName:z,startTime:X,filterPattern:m?.filter,limit:200});if(re.length)Y(re),X=(re[re.length-1].timestamp??X)+1}}}catch(X){r(`Failed to read logs: ${X.message}`),process.exitCode=1}})}async function $d(D){let t=Bun.spawn(["docker",...D],{stdin:"inherit",stdout:"inherit",stderr:"pipe"}),[m,A]=await Promise.all([t.exited,new Response(t.stderr).text()]);return{ok:m===0,exitCode:m,command:["docker",...D].join(" "),stderr:A.trim()}}function sc(D){D.command("container:build","Build a Docker image").option("--tag <tag>","Image tag",{default:"latest"}).option("--file <dockerfile>","Dockerfile",{default:"Dockerfile"}).option("--dry-run","Print the exact command").option("--json","Print result JSON").action(async(t)=>{let m=["build","--file",t.file??"Dockerfile","--tag",t.tag??"latest","."];if(t.dryRun){console.log(`docker ${m.join(" ")}`);return}let A=await $d(m);if(t.json)console.log(JSON.stringify(A));if(!A.ok)r(A.stderr||`docker exited ${A.exitCode}`),process.exitCode=A.exitCode;else n(`Built ${t.tag??"latest"}.`)}),D.command("container:push","Push an already-tagged image").option("--image <image>","Full registry image reference").option("--dry-run","Print command").option("--json","Print JSON").action(async(t)=>{if(!t.image){r("--image with a full registry reference is required; credentials must come from docker credential helpers."),process.exitCode=2;return}if(t.dryRun){console.log(`docker push ${t.image}`);return}let m=await $d(["push",t.image]);if(t.json)console.log(JSON.stringify(m));if(!m.ok)r(m.stderr),process.exitCode=m.exitCode;else n(`Pushed ${t.image}.`)}),D.command("container:deploy","Deploy a container image").action(async()=>Rn("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 ac(D){D.command("domain:list","List all domains").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t)=>{i("Domains");try{let m=Ur(t?.provider),A=fn(t?.provider)?.provider||"unknown",_=new s(`Fetching domains from ${A}...`);_.start();let z=await m.listDomains();if(_.succeed(`Found ${z.length} domain(s)`),z.length===0){e("No domains found in this provider");return}let U=z.map((Y)=>[Y,"Active","-",A.charAt(0).toUpperCase()+A.slice(1)]);c(["Domain","Status","SSL","Provider"],U)}catch(m){r(`Failed to list domains: ${m instanceof Error?m.message:String(m)}`)}}),D.command("domain:add <domain>","Add a new domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t,m)=>{i(`Adding Domain: ${t}`);try{let A=Ur(m?.provider),_=fn(m?.provider)?.provider||"unknown",z=new s(`Checking if ${_} can manage ${t}...`);if(z.start(),await A.canManageDomain(t))z.succeed(`Domain ${t} is already available in ${_}`),e(`
@@ -372,7 +372,7 @@ Deployment complete!`),e(`Total size: ${be} MB`),e(`
372
372
  Assets URL: https://${z}.s3.${A}.amazonaws.com${U?`/${U}`:""}`)}catch(m){r(`Deployment failed: ${m.message}`)}}),D.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 _=(t?.paths||"/*").split(",").map((re)=>re.trim()),z=t?.wait||!1;if(e(`Distribution: ${m}`),e(`Paths: ${_.join(", ")}`),!await u(`
373
373
  Invalidate cache now?`,!0)){e("Invalidation cancelled");return}let Y=new E,X=new s("Creating invalidation...");X.start();let ne=await Y.invalidatePaths(m,_);if(X.succeed("Invalidation created"),n(`
374
374
  Invalidation ID: ${ne.Id}`),e(`Status: ${ne.Status}`),e(`Created: ${new Date(ne.CreateTime).toLocaleString()}`),z){let re=new s("Waiting for invalidation to complete...");re.start(),await Y.waitForInvalidation(m,ne.Id),re.succeed("Invalidation completed!")}else e(`
375
- Invalidation is in progress. Use --wait to wait for completion.`)}catch(m){r(`Invalidation failed: ${m.message}`)}})}function Uc(D){for(let[t,m]of[["team:add <email> <role>","Invite an organization member"],["team:list","List organization members"],["team:remove <email>","Revoke organization membership"]])D.command(t,m).action(async(...A)=>Rn(t.split(" ")[0],{target:String(A[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 Gf,execSync as cl}from"node:child_process";import{copyFileSync as Ds,existsSync as bn,mkdirSync as iu,readFileSync as al,writeFileSync as Hf}from"node:fs";import{tmpdir as ou}from"node:os";import{dirname as Kf,join as su,resolve as Jf}from"node:path";import{existsSync as Wc,readdirSync as zd,statSync as Vc}from"node:fs";import{join as na}from"node:path";var lf=new Set([".DS_Store","Thumbs.db",".gitkeep",".keep"]);function Ud(D){return lf.has(D)}function Wd(D,t=0){if(t>8)return!0;let m;try{m=zd(D)}catch{return!1}for(let A of m){if(Ud(A))continue;let _=na(D,A),z;try{z=Vc(_)}catch{continue}if(z.isFile())return!0;if(z.isDirectory()&&Wd(_,t+1))return!0}return!1}function df(D){let t;try{t=zd(D)}catch{return[]}let m=[];for(let A of t){if(Ud(A))continue;let _=na(D,A);try{if(Vc(_).isDirectory()&&Wc(na(_,"index.html")))m.push(A)}catch{}}return m.sort((A,_)=>A.localeCompare(_))}function Vd(D){let{root:t,siteName:m,expectIndex:A}=D,_=[];if(!Wc(t))return _.push({level:"error",message:`Build output not found at ${t} for site '${m}'`}),_;if(!Vc(t).isDirectory())return _.push({level:"error",message:`Site '${m}' has root ${t}, which is a file, not a directory`}),_;if(!Wd(t))return _.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.`}),_;if(!A)return _;if(Wc(na(t,"index.html")))return _;let z=df(t);if(z.length===1){let U=`${t.replace(/\/+$/,"")}/${z[0]}`;return _.push({level:"error",message:`Site '${m}' has no index.html at the top of ${t}, but ${U} has one. The generator wrote one level down, so this release would serve 404s at the domain root. Set root: '${U}'.`}),_}if(z.length>1)return _.push({level:"warning",message:`Site '${m}' has no index.html at the top of ${t}. These subdirectories have one: ${z.join(", ")}. The domain root will 404.`}),_;return _.push({level:"warning",message:`Site '${m}' has no index.html anywhere under ${t}. The domain root will 404.`}),_}function uf(D){if(!D)return[];if(Array.isArray(D))return D.map(String);let t=D,m=t.Items??t.Item;if(!m)return[];if(Array.isArray(m))return m.map(String);if(typeof m==="object"&&m!==null){let A=m;if("Item"in A){let _=A.Item;if(!_)return[];return Array.isArray(_)?_.map(String):[String(_)]}if("CNAME"in A){let _=A.CNAME;if(!_)return[];return Array.isArray(_)?_.map(String):[String(_)]}return Object.values(A).flatMap((_)=>{if(Array.isArray(_))return _.map(String);return typeof _==="string"?[_]:[]})}return[String(m)]}async function ra(D){if(D.length===0)return;let t=new E,m=await t.listDistributions(),A=[...new Set(D.map((_)=>_.toLowerCase()))];for(let _ of A){let z=m.find((Y)=>uf(Y.Aliases).some((ne)=>ne.toLowerCase()===_));if(!z?.Id){a(`No CloudFront distribution found for ${_} — skipping dynamic HTTP method sync`);continue}if(await t.ensureDynamicHttpMethods(z.Id))n(`CloudFront ${z.Id} (${_}): enabled POST/PUT/PATCH/DELETE on dynamic paths`);else e(`CloudFront ${z.Id} (${_}): already allows dynamic HTTP methods`)}}import{execSync as mf}from"node:child_process";async function pf(D,t,m,A={},_=process.cwd()){if(!D)return;if(A.step?.(`Running ${m} hook`),typeof D==="string"){mf(D,{stdio:"inherit",cwd:_});return}await D(t)}async function Cs(D,t,m={},A){try{return await pf(D.hooks?.[t],D,t,m,A),!0}catch(_){return m.error?.(`${t} hook failed: ${_?.message||_}`),!1}}var pi=(D)=>D===void 0?void 0:D?"on":"off";function Gc(D){let t={ssl:D.ssl,always_use_https:pi(D.alwaysUseHttps),automatic_https_rewrites:pi(D.automaticHttpsRewrites),min_tls_version:D.minTlsVersion,tls_1_3:pi(D.tls13),brotli:pi(D.brotli),http3:pi(D.http3),"0rtt":pi(D.zeroRtt),early_hints:pi(D.earlyHints),browser_cache_ttl:D.browserCacheTtl,always_online:pi(D.alwaysOnline),websockets:pi(D.websockets),email_obfuscation:pi(D.emailObfuscation)};if(D.hsts)t.security_header={strict_transport_security:{enabled:D.hsts.enabled,max_age:D.hsts.maxAge??31536000,include_subdomains:D.hsts.includeSubdomains??!1,preload:D.hsts.preload??!1,nosniff:D.hsts.noSniff??!0}};for(let m of Object.keys(t))if(t[m]===void 0)delete t[m];return{...t,...D.raw??{}}}var $s={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 ff}from"node:tls";async function Kc(D){let{address:t,serverName:m,port:A=443,timeoutMs:_=5000}=D;return new Promise((z)=>{let U=!1,Y=(ne)=>{if(U)return;U=!0;try{X.destroy()}catch{}z(ne)},X=ff({host:t,port:A,servername:m,rejectUnauthorized:!1,timeout:_});X.once("secureConnect",()=>{if(X.authorized){Y({reachable:!0,trusted:!0});return}Y({reachable:!0,trusted:!1,reason:X.authorizationError?String(X.authorizationError):"origin certificate is not trusted for this hostname"})}),X.once("timeout",()=>{Y({reachable:!1,trusted:!1,reason:`no TLS handshake within ${_}ms`})}),X.once("error",(ne)=>{Y({reachable:!1,trusted:!1,reason:ne.message})})})}function gf(D,t){let m=t.replace(/\.$/,"").toLowerCase();return D.some((A)=>{let _=A.replace(/\.$/,"").toLowerCase();if(_===m)return!0;if(!_.startsWith("*."))return!1;let z=_.slice(2);if(!m.endsWith(`.${z}`))return!1;return!m.slice(0,m.length-z.length-1).includes(".")})}async function Jc(D){let{provider:t,zone:m,hosts:A,ipv4:_,ipv6:z,proxied:U=!0,settings:Y=$s,cache:X,originGuard:ne,purge:re=!0,ttl:ie=300,skipOriginProbe:ae=!1,skipEdgeCertificateCheck:be=!1}=D,ke={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(A.length===0)return ke;let le=[],$e=U&&!be?await t.listEdgeCertificateHosts(m):null;for(let Se of A){let Ae=U;if(Ae&&$e&&!gf($e,Se)){Ae=!1;let ze=$e.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${$e.join(", ")})`;ke.deferredProxy.push({host:Se,reason:ze}),ke.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(Ae&&!ae){let ze=await Kc({address:_,serverName:Se});if(!ze.trusted){Ae=!1;let Ne=ze.reason||"origin is not serving a trusted certificate";ke.deferredProxy.push({host:Se,reason:Ne}),ke.warnings.push(`${Se}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${Ne}). 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(Ae)le.push(Se);let Re=[{type:"A",content:_}];if(z&&Ji(Se))Re.push({type:"AAAA",content:z});for(let{type:ze,content:Ne}of Re){let je=await t.upsertRecord(m,{name:Se,type:ze,content:Ne,ttl:ie,proxied:Ae});if(je.success)ke.records.push({host:Se,type:ze,content:Ne,proxied:Ae});else ke.warnings.push(`${Se} ${ze} → ${Ne} failed: ${je.message||"unknown provider error"}`)}}if(le.length===0){if(U)ke.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return ke}try{let Se=Gc(Y),Ae=await t.applyZoneSettings(m,Se);ke.settingsChanged=Ae.changed;for(let Re of Ae.failed)ke.warnings.push(`zone setting '${Re.id}' could not be applied: ${Re.error}`)}catch(Se){ke.warnings.push(`zone settings could not be read: ${Se instanceof Error?Se.message:String(Se)}`)}let Pe=_s(le,X);if(Pe.length>0){let Se=await t.putManagedPhaseRules(m,"http_request_cache_settings",Pe);if(Se.success)ke.cacheRules=Pe.length;else ke.warnings.push(`cache rules could not be written: ${Se.message}`)}if(ne){let Se=Os(le,ne.header,ne.value);if(Se.length>0){let Ae=await t.putManagedPhaseRules(m,"http_request_late_transform",Se);if(Ae.success)ke.originGuard=!0;else ke.warnings.push(`origin guard header could not be written: ${Ae.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(re){if(ke.purged=await t.purgeCache(m,{hosts:le}),!ke.purged)ke.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return ke}var hf=(D)=>process.env[D];function qd(D,t){let m=D.replace(/\.$/,"").toLowerCase();if(t){let A=t.replace(/\.$/,"").toLowerCase();if(m===A||m.endsWith(`.${A}`))return A}return m.split(".").slice(-2).join(".")}function Yc(D,t={}){let m=t.env??hf,A=D.infrastructure?.compute?.proxy?.cdn,_=[];if(!A||A.provider!=="cloudflare")return{plan:null,errors:_};if(A.originDomain)_.push(`compute.proxy.cdn.originDomain (${A.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 z=m("CLOUDFLARE_API_TOKEN");if(!z)return _.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:_};let U=D.sites??{},Y=A.frontedHosts?.length?[...new Set(A.frontedHosts.map((ae)=>ae.toLowerCase()))]:Yi(U,{autoWww:D.infrastructure?.compute?.proxy?.autoWww!==!1});if(Y.length===0)return _.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:_};let X=D.infrastructure?.dns?.domain,ne=new Set(Y.map((ae)=>qd(ae,X)));if(ne.size>1)return _.push(`Fronted hosts span more than one zone (${[...ne].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:_};let re=A.cloudflare??{},ie=A.secret?{header:A.secretHeader??"X-Origin-Verify",value:A.secret}:void 0;return{plan:{zone:[...ne][0],hosts:Y,apiToken:z,zoneId:re.zoneId??m("CLOUDFLARE_ZONE_ID"),accountId:re.accountId??m("CLOUDFLARE_ACCOUNT_ID"),proxied:re.proxied!==!1,settings:re.settings??$s,cache:re.cache,originGuard:ie,purge:re.purgeOnDeploy!==!1,skipOriginProbe:re.skipOriginProbe===!0},errors:_}}var yf="https://api.cloudflare.com/client/v4",Hd=10042,vf=10006,bf=10059;class ho extends Error{status;errors;constructor(D,t,m=[]){super(D);this.name="R2ApiError",this.status=t,this.errors=m}hasCode(D){return this.errors.some((t)=>t.code===D)}}class Ui extends ho{accountId;constructor(D,t,m=[]){super(`R2 is not enabled on Cloudflare account ${D}. 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=D}}class jo{name="cloudflare-r2";apiToken;accountId;fetchImpl;constructor(D){if(!D.apiToken)throw Error("Cloudflare R2 needs an API token");if(!D.accountId)throw Error("Cloudflare R2 needs an account id");this.apiToken=D.apiToken,this.accountId=D.accountId,this.fetchImpl=D.fetch??((t,m)=>fetch(t,m))}async requestEnvelope(D,t,m,A={}){let _={Authorization:`Bearer ${this.apiToken}`};if(m!==void 0)_["Content-Type"]="application/json";if(A.jurisdiction&&A.jurisdiction!=="default")_["cf-r2-jurisdiction"]=A.jurisdiction;let z=await this.fetchImpl(`${yf}/accounts/${this.accountId}/r2${t}`,{method:D,headers:_,body:m===void 0?void 0:JSON.stringify(m)}),U=await z.text(),Y;try{Y=JSON.parse(U)}catch{throw new ho(`Cloudflare R2 API returned ${z.status} with a non-JSON body: ${U.slice(0,200)}`,z.status)}if(!Y.success){let X=Y.errors??[];if(X.some((re)=>re.code===Hd))throw new Ui(this.accountId,z.status,X);let ne=X.map((re)=>`${re.code}: ${re.message}`).join(", ");throw new ho(`Cloudflare R2 API error (${z.status}) on ${D} ${t}: ${ne||U.slice(0,200)}`,z.status,X)}return Y}async request(D,t,m,A){return(await this.requestEnvelope(D,t,m,A)).result}bucketPath(D){return`/buckets/${encodeURIComponent(D)}`}async listBuckets(D={}){let t=[],m;do{let A=new URLSearchParams({per_page:"1000"});if(m)A.set("cursor",m);let _=await this.requestEnvelope("GET",`/buckets?${A}`,void 0,D),z=_.result?.buckets??[];t.push(...z),m=z.length>0?_.result_info?.cursor||void 0:void 0}while(m);return t}async getBucket(D,t={}){try{return await this.request("GET",this.bucketPath(D),void 0,t)}catch(m){if(m instanceof Ui)throw m;if(m instanceof ho&&(m.hasCode(vf)||m.status===404))return null;throw m}}async ensureBucket(D,t={}){let m={jurisdiction:t.jurisdiction},A=await this.getBucket(D,m);if(A)return{bucket:A,created:!1};let _={name:D};if(t.locationHint)_.locationHint=t.locationHint;let z=await this.request("POST","/buckets",_,m);return{bucket:{...z,name:z?.name||D},created:!0}}async getCors(D,t={}){try{return(await this.request("GET",`${this.bucketPath(D)}/cors`,void 0,t))?.rules??[]}catch(m){if(m instanceof ho&&!(m instanceof Ui)&&(m.hasCode(bf)||m.status===404))return[];throw m}}async putCors(D,t,m={}){if(t.length===0){await this.request("DELETE",`${this.bucketPath(D)}/cors`,void 0,m);return}await this.request("PUT",`${this.bucketPath(D)}/cors`,{rules:t},m)}async ensureCors(D,t,m={}){let A=await this.getCors(D,m);if(oa(A,t))return!1;return await this.putCors(D,t,m),!0}async getLifecycle(D,t={}){return(await this.request("GET",`${this.bucketPath(D)}/lifecycle`,void 0,t))?.rules??[]}async putLifecycle(D,t,m={}){await this.request("PUT",`${this.bucketPath(D)}/lifecycle`,{rules:t},m)}async ensureLifecycle(D,t,m={}){let A=await this.getLifecycle(D,m);if(sa(A,t))return!1;return await this.putLifecycle(D,t,m),!0}async listCustomDomains(D,t={}){return(await this.request("GET",`${this.bucketPath(D)}/domains/custom`,void 0,t))?.domains??[]}async attachCustomDomain(D,t,m={}){return this.request("POST",`${this.bucketPath(D)}/domains/custom`,{domain:t.domain,zoneId:t.zoneId,enabled:t.enabled??!0,minTLS:t.minTLS??"1.2"},m)}async updateCustomDomain(D,t,m,A={}){return this.request("PUT",`${this.bucketPath(D)}/domains/custom/${encodeURIComponent(t)}`,m,A)}async ensureCustomDomain(D,t,m={},A){let _=t.minTLS??"1.2",U=(A??await this.listCustomDomains(D,m)).find((ne)=>ne.domain.toLowerCase()===t.domain.toLowerCase());if(!U){let ne=await this.attachCustomDomain(D,{...t,minTLS:_,enabled:!0},m);return{action:"attached",domain:{...ne,domain:ne?.domain||t.domain}}}let Y=U.minTLS??"1.0";if(U.enabled&&Y===_)return{action:"unchanged",domain:U};let X=await this.updateCustomDomain(D,U.domain,{enabled:!0,minTLS:_},m);return{action:"updated",domain:{...U,...X}}}async getManagedDomain(D,t={}){return this.request("GET",`${this.bucketPath(D)}/domains/managed`,void 0,t)}async setManagedDomain(D,t,m={}){let A=await this.getManagedDomain(D,m);if(A?.enabled===t)return{changed:!1,domain:A};return{changed:!0,domain:await this.request("PUT",`${this.bucketPath(D)}/domains/managed`,{enabled:t},m)}}}function As(D){if(Array.isArray(D))return`[${D.map(As).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${As(A)}`).join(",")}}`;return JSON.stringify(D)}function Gd(D,t){let m=(A)=>A&&A.length>0?[...A].map(String).sort():void 0;return{id:t?D.id:void 0,allowed:{origins:m(D.allowed?.origins),methods:m(D.allowed?.methods?.map((A)=>A.toUpperCase())),headers:m(D.allowed?.headers?.map((A)=>A.toLowerCase()))},exposeHeaders:m(D.exposeHeaders?.map((A)=>A.toLowerCase())),maxAgeSeconds:D.maxAgeSeconds}}function oa(D,t){if(D.length!==t.length)return!1;return t.every((m,A)=>{let _=m.id!==void 0;return As(Gd(D[A],_))===As(Gd(m,_))})}function sa(D,t){if(D.length!==t.length)return!1;let m=(A)=>As([...A].map((_)=>({..._,storageClassTransitions:_.storageClassTransitions?.length?_.storageClassTransitions:void 0})).sort((_,z)=>_.id.localeCompare(z.id)));return m(D)===m(t)}var wf="r2 cache",Sf=/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;async function Xc(D,t={}){let m=t.log??(()=>{}),A={buckets:[],warnings:[]},_=D.infrastructure?.r2??D.r2,z=Object.entries(_?.buckets??{});if(z.length===0)return m("R2: no buckets declared, skipping."),A;if(!t.apiToken||!t.accountId){let re=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),ie=`R2: ${z.length} bucket(s) declared but ${re} is not set, skipping.`;return m(ie),A.warnings.push(ie),A}let U=t.dryRun===!0,Y=new jo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),X=new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),ne=new Map;for(let[re,ie]of z){let ae=ie?.name;if(!ae||!Sf.test(ae)){A.warnings.push(`R2: bucket '${re}' has an invalid name '${ae??""}' (3-63 chars: lowercase letters, digits, hyphens), skipping.`);continue}m(`R2: ${U?"checking":"reconciling"} bucket ${ae}...`);let be={name:ae,changes:[],domains:[]};if(A.buckets.push(be),await Cf(ie,{r2:Y,cloudflare:X,dryRun:U,summary:be,warnings:A.warnings,claimed:ne,log:m}),be.changes.length===0)m(`R2: ${ae} is in sync.`);else for(let ke of be.changes)m(`R2: ${ae}: ${ke}`)}return A}async function Cf(D,t){let{r2:m,dryRun:A,summary:_,warnings:z}=t,U=D.name,Y={jurisdiction:D.jurisdiction},X=(be,ke)=>{let le=A?ke&&`would ${ke}`:be;if(le)_.changes.push(le)},ne;if(A)ne=await m.getBucket(U,Y)!==null;else{let{created:be}=await m.ensureBucket(U,{locationHint:D.locationHint,jurisdiction:D.jurisdiction});if(ne=!0,be)X("created","")}if(!ne)X("","create bucket");let re=kf(D.customDomains);await Rs(t,`cors on ${U}`,async()=>{if(!D.cors)return;if(!ne){X("cors updated","set cors");return}let be=await m.getCors(U,Y);if(oa(be,D.cors))return;if(!A)await m.putCors(U,D.cors,Y);X(D.cors.length===0?"cors removed":"cors updated",D.cors.length===0?"remove cors":"update cors")}),await Rs(t,`lifecycle on ${U}`,async()=>{if(!D.lifecycle)return;let be=D.lifecycle.map(Yd);if(ne){let ke=await m.getLifecycle(U,Y);if(sa(ke,be))return}if(!A)await m.putLifecycle(U,be,Y);X("lifecycle updated","update lifecycle")}),await Rs(t,`r2.dev URL on ${U}`,async()=>{let be=D.publicDevUrl===!0;if(!ne){if(be)X("r2.dev URL enabled","enable r2.dev URL");return}if((await m.getManagedDomain(U,Y))?.enabled===be)return;if(!A)await m.setManagedDomain(U,be,Y);X(be?"r2.dev URL enabled":"r2.dev URL disabled",be?"enable r2.dev URL":"disable r2.dev URL")});let ie=[];if(re.length>0&&ne)try{ie=await m.listCustomDomains(U,Y)}catch(be){if(be instanceof Ui)throw be;z.push(`R2: could not list custom domains on ${U}: ${el(be)}`)}let ae=new Map;for(let{domain:be,minTLS:ke}of re){let le=t.claimed.get(be);if(le&&le!==U){z.push(`R2: ${be} is declared on both ${le} and ${U}; leaving it on ${le}.`);continue}t.claimed.set(be,U);let $e=ie.find((Se)=>Se.domain.toLowerCase()===be),Pe=ke??"1.2";if($e&&$e.enabled&&($e.minTLS??"1.0")===Pe){if(_.domains.push({domain:be,status:Qc($e)}),$e.zoneId)ae.set(be,$e.zoneId);continue}await Rs(t,`custom domain ${be} on ${U}`,async()=>{if($e){if(!A)await m.updateCustomDomain(U,$e.domain,{enabled:!0,minTLS:Pe},Y);if(X(`custom domain ${be} updated`,`update custom domain ${be}`),_.domains.push({domain:be,status:Qc({...$e,enabled:!0})}),$e.zoneId)ae.set(be,$e.zoneId);return}let Se=await t.cloudflare.zoneIdFor(be);if(ae.set(be,Se),!A)await m.ensureCustomDomain(U,{domain:be,zoneId:Se,minTLS:Pe},Y,ie);X(`custom domain ${be} attached`,`attach custom domain ${be}`),_.domains.push({domain:be,status:A?"not attached":"pending"})},()=>_.domains.push({domain:be,status:"error"}))}if(D.cache&&re.length>0)await $f(D,re.map((be)=>be.domain).filter((be)=>t.claimed.get(be)===U),ae,t,X)}async function $f(D,t,m,A,_){let z=Kd(D.cache);if(!z||t.length===0)return;let U=new Map;for(let Y of t){let X=m.get(Y);if(!X)try{X=await A.cloudflare.zoneIdFor(Y)}catch(ne){A.warnings.push(`R2: could not resolve the zone for ${Y}, cache rule skipped: ${el(ne)}`);continue}U.set(X,[...U.get(X)??[],Y])}for(let Y of U.values()){let X={action:"set_cache_settings",description:`${Ar} ${wf}`,expression:`(${wr(Y)})`,enabled:!0,action_parameters:z};await Rs(A,`cache rule for ${Y.join(", ")}`,async()=>{let ne=await A.cloudflare.getPhaseRules(Y[0],"http_request_cache_settings");if(Jd(ne,X))return;if(!A.dryRun){let re=await A.cloudflare.putManagedPhaseRules(Y[0],"http_request_cache_settings",[X]);if(!re.success)throw Error(re.message||"cache rule write failed")}_(`cache rule updated for ${Y.join(", ")}`,`update cache rule for ${Y.join(", ")}`)})}}function Kd(D){if(D.edgeTtl===void 0&&D.browserTtl===void 0)return null;let t={cache:!0};if(D.edgeTtl!==void 0)t.edge_ttl={mode:"override_origin",default:D.edgeTtl};if(D.browserTtl!==void 0)t.browser_ttl={mode:"override_origin",default:D.browserTtl};return t}function Jd(D,t){let m=Rr(t.expression),A=wi(t.expression),_=(Y)=>(Y.description||"").startsWith(Ar),z=(Y)=>Y.action===t.action&&Y.description===t.description&&(Y.enabled??!0)===(t.enabled??!0)&&wi(Y.expression)===A&&aa(Y.action_parameters)===aa(t.action_parameters),U=!1;for(let Y of D){if(!_(Y))continue;let X=Rr(Y.expression);if(!m.some((re)=>X.includes(re)))continue;if(z(Y)&&m.every((re)=>X.includes(re))&&!U){U=!0;continue}return!1}return U}function Yd(D){let t={id:D.id,enabled:D.enabled??!0,conditions:{prefix:D.prefix??""}};if(D.expireAfterDays!==void 0)t.deleteObjectsTransition={condition:{type:"Age",maxAge:Zc(D.expireAfterDays)}};else if(D.expireOn!==void 0)t.deleteObjectsTransition={condition:{type:"Date",date:D.expireOn}};if(D.abortMultipartUploadsAfterDays!==void 0)t.abortMultipartUploadsTransition={condition:{type:"Age",maxAge:Zc(D.abortMultipartUploadsAfterDays)}};if(D.infrequentAccessAfterDays!==void 0)t.storageClassTransitions=[{storageClass:"InfrequentAccess",condition:{type:"Age",maxAge:Zc(D.infrequentAccessAfterDays)}}];return t}function Zc(D){return Math.round(D*86400)}function kf(D){let t=new Set,m=[];for(let A of D??[]){let _=typeof A==="string"?{domain:A}:A,z=_.domain?.trim().replace(/\.$/,"").toLowerCase();if(!z||t.has(z))continue;t.add(z),m.push({domain:z,minTLS:_.minTLS})}return m}function Qc(D){if(!D.enabled)return"disabled";let t=D.status?.ownership,m=D.status?.ssl;if(t==="active"&&m==="active")return"active";for(let A of[t,m])if(A==="error"||A==="blocked"||A==="deactivated")return A;return"pending"}async function Rs(D,t,m,A){try{await m()}catch(_){if(_ instanceof Ui)throw _;D.warnings.push(`R2: ${t} failed: ${el(_)}`),A?.()}}function el(D){return D instanceof Error?D.message:String(D)}function aa(D){if(Array.isArray(D))return`[${D.map(aa).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${aa(A)}`).join(",")}}`;return JSON.stringify(D)}import{basename as Ef,extname as Tf}from"node:path";import{createHash as Af}from"node:crypto";var Rf="https://api.cloudflare.com/client/v4",Vi="TS_CLOUD_CONTENT_HASH",Is="2025-09-01",nl="application/javascript+module",If=10007,Pf=[1e4,9109];class Bo extends Error{status;errors;constructor(D,t,m=[]){super(D);this.name="WorkersApiError",this.status=t,this.errors=m}hasCode(D){return this.errors.some((t)=>t.code===D)}}class ca extends Bo{permission;constructor(D,t,m,A=[]){super(`The Cloudflare API token is missing the "${D}" permission (${t}). Edit the token in the Cloudflare dashboard (My Profile, API Tokens), add it, then re-run the deploy.`,m,A);this.name="WorkersPermissionError",this.permission=D}}class da{name="cloudflare-workers";apiToken;accountId;fetchImpl;constructor(D){if(!D.apiToken)throw Error("Cloudflare Workers needs an API token");if(!D.accountId)throw Error("Cloudflare Workers needs an account id");this.apiToken=D.apiToken,this.accountId=D.accountId,this.fetchImpl=D.fetch??((t,m)=>fetch(t,m))}async request(D,t,m){let A={Authorization:`Bearer ${this.apiToken}`},_;if(m instanceof FormData)_=m;else if(m!==void 0)A["Content-Type"]="application/json",_=JSON.stringify(m);let z=await this.fetchImpl(`${Rf}/accounts/${this.accountId}/workers${t}`,{method:D,headers:A,body:_}),U=await z.text(),Y;try{Y=JSON.parse(U)}catch{throw new Bo(`Cloudflare Workers API returned ${z.status} with a non-JSON body: ${U.slice(0,200)}`,z.status)}if(!Y.success){let X=Y.errors??[],ne=X.map((re)=>`${re.code}: ${re.message}`).join(", ");if(Df(z.status,X))throw new ca(xf(t),`${D} ${t} -> ${z.status}${ne?`, ${ne}`:""}`,z.status,X);throw new Bo(`Cloudflare Workers API error (${z.status}) on ${D} ${t}: ${ne||U.slice(0,200)}`,z.status,X)}return Y.result}scriptPath(D){return`/scripts/${encodeURIComponent(D)}`}async getSettings(D){try{return await this.request("GET",`${this.scriptPath(D)}/settings`)}catch(t){if(t instanceof ca)throw t;if(t instanceof Bo&&(t.hasCode(If)||t.status===404))return null;throw t}}async getScript(D){return this.getSettings(D)}async uploadModuleScript(D,t){return this.request("PUT",this.scriptPath(D),Qd(t))}async ensureModuleScript(D,t){let m=Ps(t),A=await this.getSettings(D);if(A&&fa(A,t,m))return{action:"unchanged",hash:m};return await this.uploadModuleScript(D,Xd(t,m)),{action:A?"updated":"created",hash:m}}async listCustomDomains(D={}){let t=new URLSearchParams;if(D.service)t.set("service",D.service);if(D.hostname)t.set("hostname",D.hostname);if(D.zoneId)t.set("zone_id",D.zoneId);let m=t.toString(),A=m?`?${m}`:"";return await this.request("GET",`/domains${A}`)??[]}async attachCustomDomain(D,t){let m={hostname:D,service:t.service,environment:t.environment??"production"};if(t.zoneId)m.zone_id=t.zoneId;return this.request("PUT","/domains",m)}async detachCustomDomain(D){await this.request("DELETE",`/domains/${encodeURIComponent(D)}`)}async ensureCustomDomain(D,t,m){let _=(m??await this.listCustomDomains({hostname:D})).find((U)=>U.hostname.toLowerCase()===D.toLowerCase());if(_&&_.service===t.service)return{action:"unchanged",domain:_};if(_)throw Error(`${D} is attached to the Worker '${_.service}'. Detach it there first (Workers & Pages, ${_.service}, Settings, Domains & Routes); ts-cloud does not move it.`);let z=await this.attachCustomDomain(D,t);return{action:"attached",domain:{...z,hostname:z?.hostname||D}}}}function Df(D,t){if(t.some((m)=>Pf.includes(m.code)))return!0;return(D===401||D===403)&&t.length===0}function xf(D){if(D.startsWith("/domains"))return"Workers Routes: Edit (zone, for Workers custom domains) and Workers Scripts: Edit (account)";return"Workers Scripts: Edit (account)"}function Qd(D){if(!D.modules.some((A)=>A.name===D.mainModule))throw Error(`Worker main module '${D.mainModule}' is not one of the uploaded modules`);let t={main_module:D.mainModule,bindings:D.bindings??[],compatibility_date:D.compatibilityDate??Is,compatibility_flags:D.compatibilityFlags??[],keep_bindings:["secret_text"]},m=new FormData;m.append("metadata",JSON.stringify(t));for(let A of D.modules)m.append(A.name,new Blob([A.content],{type:A.type}),A.name);return m}function Ps(D){let t={mainModule:D.mainModule,modules:[...D.modules].sort((m,A)=>m.name.localeCompare(A.name)).map((m)=>({name:m.name,type:m.type,sha256:Zd(m.content)})),bindings:[...D.bindings??[]].filter((m)=>m.name!==Vi).sort((m,A)=>m.name.localeCompare(A.name)),compatibilityDate:D.compatibilityDate??Is,compatibilityFlags:[...D.compatibilityFlags??[]].sort()};return Zd(tl(t))}function Xd(D,t=Ps(D)){return{...D,bindings:[...(D.bindings??[]).filter((m)=>m.name!==Vi),{type:"plain_text",name:Vi,text:t}]}}function fa(D,t,m){let A=D.bindings??[],_=A.find((z)=>z.name===Vi&&z.type==="plain_text");if(!_||_.text!==m)return!1;return(t.bindings??[]).every((z)=>{let U=A.find((X)=>X.name===z.name);if(!U||U.type!==z.type)return!1;let Y=z.type==="r2_bucket"?"bucket_name":z.type==="plain_text"?"text":void 0;return!Y||U[Y]===z[Y]})}function Zd(D){return Af("sha256").update(D).digest("hex")}function tl(D){if(Array.isArray(D))return`[${D.map(tl).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${tl(A)}`).join(",")}}`;return JSON.stringify(D)}async function rl(D){if(!await Bun.file(D).exists())throw Error(`Worker entry not found: ${D}`);let t;try{t=await Bun.build({entrypoints:[D],target:"browser",format:"esm",minify:!0,external:["cloudflare:*"]})}catch(_){throw Error(`Bundling Worker ${D} failed: ${Nf(_)}`)}if(!t.success)throw Error(`Bundling Worker ${D} failed: ${t.logs.map((_)=>String(_.message??_)).join("; ")}`);if(t.outputs.length!==1)throw Error(`Bundling Worker ${D} produced ${t.outputs.length} files (${t.outputs.map((_)=>_.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 ${D} produced a ${m.kind} instead of an entry module`);let A=await m.text();return{name:`${Ef(D,Tf(D))}.js`,content:A,type:nl,size:new TextEncoder().encode(A).byteLength}}function Nf(D){if(D instanceof AggregateError&&D.errors.length>0)return D.errors.map((t)=>t instanceof Error?t.message:String(t?.message??t)).join("; ");return D instanceof Error?D.message:String(D)}import{isAbsolute as Of,resolve as Lf}from"node:path";var Ff="https://api.cloudflare.com/client/v4",jf=/^[a-z0-9][a-z0-9_-]{0,62}$/;async function il(D,t={}){let m=t.log??(()=>{}),A={workers:[],warnings:[]},_=Object.entries(D.infrastructure?.workers??D.workers??{});if(_.length===0)return m("Workers: none declared, skipping."),A;if(!t.apiToken||!t.accountId){let Y=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),X=`Workers: ${_.length} Worker(s) declared but ${Y} is not set, skipping.`;return m(X),A.warnings.push(X),A}let z=D.infrastructure?.r2??D.r2,U={workers:new da({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),r2:new jo({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,X)=>fetch(Y,X)),projectRoot:t.projectRoot??process.cwd(),dryRun:t.dryRun===!0,warnings:A.warnings,log:m,r2ConfigDomains:Wf(z),r2Buckets:z,claimed:new Map};for(let[Y,X]of _){let ne=X?.name;if(!ne||!jf.test(ne)){A.warnings.push(`Workers: '${Y}' has an invalid name '${ne??""}' (1-63 chars: lowercase letters, digits, '-' and '_'), skipping.`);continue}if(!X.entry){A.warnings.push(`Workers: ${ne} has no entry, skipping.`);continue}m(`Workers: ${U.dryRun?"checking":"reconciling"} ${ne}...`);let re={name:ne,changes:[],domains:[]};A.workers.push(re),await Bf(X,re,U);for(let ie of re.changes)m(`Workers: ${ne}: ${ie}`)}return A}async function Bf(D,t,m){let A=D.name,_=Of(D.entry)?D.entry:Lf(m.projectRoot,D.entry),z;try{z=await rl(_)}catch(Y){throw Error(`Worker ${A}: ${_o(Y)}`)}t.changes.push(`bundled ${qf(z.size)}`);let U={mainModule:z.name,modules:[{name:z.name,content:z.content,type:z.type}],bindings:eu(D,m),compatibilityDate:D.compatibilityDate??Is,compatibilityFlags:D.compatibilityFlags??[]};if(m.dryRun){let Y=await m.workers.getSettings(A);t.changes.push(Y&&fa(Y,U,Ps(U))?"unchanged":"would upload")}else{let{action:Y}=await m.workers.ensureModuleScript(A,U);t.changes.push(Y==="unchanged"?"unchanged":"uploaded")}for(let Y of Vf(D.customDomains))await _f(A,Y,t,m)}async function _f(D,t,m,A){let _=(be)=>{m.domains.push({domain:t,status:be})},z=(be)=>{A.warnings.push(`Workers: ${be}`),_("conflict")},U=A.claimed.get(t);if(U&&U!==D){z(`${t} is declared on both ${U} and ${D}; leaving it on ${U}.`);return}A.claimed.set(t,D);let Y=A.r2ConfigDomains.get(t);if(Y){z(`${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 X=await Mf(A);if(X===null){_("error");return}let ne=X.find((be)=>be.hostname.toLowerCase()===t);if(ne?.service===D){_("active");return}if(ne){z(`${t} is attached to the Worker '${ne.service}'. Detach it there first (Workers & Pages, ${ne.service}, Settings, Domains & Routes); it is not moved automatically.`);return}let re=(await zf(A))?.get(t);if(re){z(`${t} is attached to the R2 bucket '${re}' as a custom domain. Detach it first (R2, ${re}, 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 A.cloudflare.zoneIdFor(t)}catch(be){A.warnings.push(`Workers: could not resolve the zone for ${t}, not attached: ${_o(be)}`),_("error");return}let ae=await Uf(A,ie,t);if(ae.length>0){let be=ae.map((ke)=>`${ke.type} ${ke.content}`).join(", ");z(`${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(A.dryRun){m.changes.push(`would attach custom domain ${t}`),_("not attached");return}try{await A.workers.ensureCustomDomain(t,{service:D,zoneId:ie},X),m.changes.push(`custom domain ${t} attached`),X.push({id:"",hostname:t,service:D,zone_id:ie}),_("pending")}catch(be){A.warnings.push(`Workers: custom domain ${t} on ${D} failed: ${_o(be)}`),_("error")}}async function Mf(D){if(D.attached!==void 0)return D.attached;try{D.attached=await D.workers.listCustomDomains()}catch(t){D.warnings.push(`Workers: could not list Worker custom domains, none attached: ${_o(t)}`),D.attached=null}return D.attached}async function zf(D){if(D.r2AccountDomains!==void 0)return D.r2AccountDomains;let t=new Map;try{let m=(await D.r2.listBuckets()).map((A)=>({name:A.name}));for(let A of Object.values(D.r2Buckets?.buckets??{}))if(A.jurisdiction&&A.jurisdiction!=="default")m.push({name:A.name,jurisdiction:A.jurisdiction});for(let A of m){let _=await D.r2.listCustomDomains(A.name,{jurisdiction:A.jurisdiction}).catch(()=>[]);for(let z of _)t.set(z.domain.toLowerCase(),A.name)}D.r2AccountDomains=t}catch(m){D.log(`Workers: could not check R2 custom domains (${_o(m)}); relying on the DNS check.`),D.r2AccountDomains=null}return D.r2AccountDomains}async function Uf(D,t,m){try{let A=await D.fetch(`${Ff}/zones/${t}/dns_records?name=${encodeURIComponent(m)}&per_page=100`,{method:"GET",headers:{Authorization:`Bearer ${D.apiToken}`}}),_=await A.json();if(!_?.success)throw Error(`HTTP ${A.status}`);return(_.result??[]).filter((z)=>z.name?.toLowerCase()===m).map((z)=>({type:z.type??"?",content:z.content??""}))}catch(A){return D.log(`Workers: could not read DNS records for ${m} (${_o(A)}); attaching anyway.`),[]}}function eu(D,t){let m=[],A=new Set,_=(U)=>{if(U===Vi)return t.warnings.push(`Workers: ${D.name}: binding name ${Vi} is reserved for ts-cloud, ignored.`),!1;if(A.has(U))return t.warnings.push(`Workers: ${D.name}: binding ${U} is declared twice; the first one wins.`),!1;return A.add(U),!0},z=new Map;for(let U of Object.values(t.r2Buckets?.buckets??{}))if(U.jurisdiction&&U.jurisdiction!=="default")z.set(U.name,U.jurisdiction);for(let[U,Y]of Object.entries(D.bindings?.r2Buckets??{})){if(!_(U))continue;let X=z.get(Y);m.push(X?{type:"r2_bucket",name:U,bucket_name:Y,jurisdiction:X}:{type:"r2_bucket",name:U,bucket_name:Y})}for(let[U,Y]of Object.entries(D.bindings?.vars??{}))if(_(U))m.push({type:"plain_text",name:U,text:String(Y)});return m}function Wf(D){let t=new Map;for(let m of Object.values(D?.buckets??{}))for(let A of m?.customDomains??[]){let _=tu(typeof A==="string"?A:A.domain);if(_)t.set(_,m.name)}return t}function Vf(D){return[...new Set((D??[]).map(tu).filter(Boolean))]}function tu(D){return(D??"").trim().replace(/\.$/,"").toLowerCase()}function qf(D){if(D<1024)return`${D} B`;if(D<1048576)return`${(D/1024).toFixed(1)} KB`;return`${(D/1024/1024).toFixed(1)} MB`}function _o(D){return D instanceof Error?D.message:String(D)}async function Yf(D){let t=ia();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 A=await new ut(D).getCallerIdentity();if(A.Arn)e(`AWS identity: ${A.Arn}`)}catch(m){a(`Could not verify AWS identity: ${m.message}`)}}function Zf(){try{return cl("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function ol(D,t,m,A){let{ensureManagementDashboard:_}=await import("./chunk-r524t8v8.js");_(D,{logger:{info:e,warn:a}});let z=D.sites||{},U=Object.entries(z);if(U.length===0)return a("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(A&&!z[A])return r(`Site '${A}' was not found. Configured sites: ${U.map(([Pe])=>Pe).join(", ")}`),!1;let Y=U.filter(([Pe,Se])=>{if(!Se)return!1;if(A&&Pe!==A)return!1;if(I(Se)==="bucket")return a(`Site '${Pe}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return Ks(Se)});if(A)e(`Deploying only '${A}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let X=D.project.slug,re=(D.infrastructure?.compute||{}).runtime||"bun",ie=O({config:D}),ae=Zf(),be=new Map,ke=new Map,le={step:(Pe)=>d(Pe),error:(Pe)=>r(Pe)};if(!await Cs(D,"beforeDeploy",le))return!1;if(!await Cs(D,"beforeBuild",le))return!1;for(let[Pe,Se]of Y){let Ae=I(Se);if(i(`Preparing site: ${Pe}`),e(`Domain: ${Se.domain||"(none)"}`),e(`Source: ${Se.root}`),e(`Kind: ${Ae==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),Ae==="server-app")e(`Start: ${Se.start}`),e(`Port: ${Se.port??"(unset)"}`);if(Se.build){d(`Running build: ${Se.build}`);try{cl(Se.build,{stdio:"inherit",cwd:process.cwd()})}catch(Ue){return r(`Build failed for site '${Pe}': ${Ue.message}`),!1}}let Re=Vd({root:Se.root,siteName:Pe,expectIndex:Ae==="server-static"});for(let Ue of Re)if(Ue.level==="error")r(Ue.message);else a(Ue.message);if(Re.some((Ue)=>Ue.level==="error"))return!1;let ze=Se.build?void 0:JSON.stringify([Jf(Se.root),[...Se.exclude||[]].sort()]),Ne=ze?ke.get(ze):void 0;if(Ne){d(`Reusing package for ${Se.root} → ${Ne}`),be.set(Pe,Ne);continue}let je=su(ou(),`${X}-${Pe}-${ae}.tar.gz`);d(`Packaging ${Se.root} → ${je}`);try{let Ue=(Se.exclude||[]).map((Ct)=>`--exclude=${Ct}`);Gf("tar",["czf",je,"-C",Se.root,...Ue,"."],{stdio:"inherit",env:{...process.env,COPYFILE_DISABLE:"1"}})}catch(Ue){return r(`Failed to package '${Pe}': ${Ue.message}`),!1}if(be.set(Pe,je),ze)ke.set(ze,je)}if(!await Cs(D,"afterBuild",le))return!1;let $e=await io({config:A?{...D,sites:Object.fromEntries(Y)}:D,rpxConfig:A?D:void 0,environment:t,driver:ie,sha:ae,runtime:re,tarballForSite:(Pe)=>{let Se=be.get(Pe);if(!Se)throw Error(`Missing tarball for site '${Pe}'`);return Se},logger:{info:(Pe)=>e(Pe),warn:(Pe)=>a(Pe),error:(Pe)=>r(Pe),step:(Pe)=>d(Pe),success:(Pe)=>n(Pe)}});if($e&&!await Cs(D,"afterDeploy",le))return!1;return $e}async function ga(D){let t=new Jr;if(d("Running pre-deployment security scan..."),D.exclude?.length)e(`Excluding from the scan: ${D.exclude.join(", ")}`);let m=await t.scan({directory:D.sourceDir,failOnSeverity:D.failOnSeverity||"critical",skipPatterns:D.skipPatterns,exclude:D.exclude});return{passed:m.passed,result:m}}function Qf(){let D=su(ou(),`ts-cloud-empty-scan-${process.pid}`);return iu(D,{recursive:!0}),D}function ha(D){let{summary:t,findings:m,scannedFiles:A,duration:_}=D;if(e(`
375
+ Invalidation is in progress. Use --wait to wait for completion.`)}catch(m){r(`Invalidation failed: ${m.message}`)}})}function Uc(D){for(let[t,m]of[["team:add <email> <role>","Invite an organization member"],["team:list","List organization members"],["team:remove <email>","Revoke organization membership"]])D.command(t,m).action(async(...A)=>Rn(t.split(" ")[0],{target:String(A[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 Gf,execSync as cl}from"node:child_process";import{copyFileSync as Ds,existsSync as bn,mkdirSync as iu,readFileSync as al,writeFileSync as Hf}from"node:fs";import{tmpdir as ou}from"node:os";import{dirname as Kf,join as su,resolve as Jf}from"node:path";import{existsSync as Wc,readdirSync as zd,statSync as Vc}from"node:fs";import{join as na}from"node:path";var lf=new Set([".DS_Store","Thumbs.db",".gitkeep",".keep"]);function Ud(D){return lf.has(D)}function Wd(D,t=0){if(t>8)return!0;let m;try{m=zd(D)}catch{return!1}for(let A of m){if(Ud(A))continue;let _=na(D,A),z;try{z=Vc(_)}catch{continue}if(z.isFile())return!0;if(z.isDirectory()&&Wd(_,t+1))return!0}return!1}function df(D){let t;try{t=zd(D)}catch{return[]}let m=[];for(let A of t){if(Ud(A))continue;let _=na(D,A);try{if(Vc(_).isDirectory()&&Wc(na(_,"index.html")))m.push(A)}catch{}}return m.sort((A,_)=>A.localeCompare(_))}function Vd(D){let{root:t,siteName:m,expectIndex:A}=D,_=[];if(!Wc(t))return _.push({level:"error",message:`Build output not found at ${t} for site '${m}'`}),_;if(!Vc(t).isDirectory())return _.push({level:"error",message:`Site '${m}' has root ${t}, which is a file, not a directory`}),_;if(!Wd(t))return _.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.`}),_;if(!A)return _;if(Wc(na(t,"index.html")))return _;let z=df(t);if(z.length===1){let U=`${t.replace(/\/+$/,"")}/${z[0]}`;return _.push({level:"error",message:`Site '${m}' has no index.html at the top of ${t}, but ${U} has one. The generator wrote one level down, so this release would serve 404s at the domain root. Set root: '${U}'.`}),_}if(z.length>1)return _.push({level:"warning",message:`Site '${m}' has no index.html at the top of ${t}. These subdirectories have one: ${z.join(", ")}. The domain root will 404.`}),_;return _.push({level:"warning",message:`Site '${m}' has no index.html anywhere under ${t}. The domain root will 404.`}),_}function uf(D){if(!D)return[];if(Array.isArray(D))return D.map(String);let t=D,m=t.Items??t.Item;if(!m)return[];if(Array.isArray(m))return m.map(String);if(typeof m==="object"&&m!==null){let A=m;if("Item"in A){let _=A.Item;if(!_)return[];return Array.isArray(_)?_.map(String):[String(_)]}if("CNAME"in A){let _=A.CNAME;if(!_)return[];return Array.isArray(_)?_.map(String):[String(_)]}return Object.values(A).flatMap((_)=>{if(Array.isArray(_))return _.map(String);return typeof _==="string"?[_]:[]})}return[String(m)]}async function ra(D){if(D.length===0)return;let t=new E,m=await t.listDistributions(),A=[...new Set(D.map((_)=>_.toLowerCase()))];for(let _ of A){let z=m.find((Y)=>uf(Y.Aliases).some((ne)=>ne.toLowerCase()===_));if(!z?.Id){a(`No CloudFront distribution found for ${_} — skipping dynamic HTTP method sync`);continue}if(await t.ensureDynamicHttpMethods(z.Id))n(`CloudFront ${z.Id} (${_}): enabled POST/PUT/PATCH/DELETE on dynamic paths`);else e(`CloudFront ${z.Id} (${_}): already allows dynamic HTTP methods`)}}import{execSync as mf}from"node:child_process";async function pf(D,t,m,A={},_=process.cwd()){if(!D)return;if(A.step?.(`Running ${m} hook`),typeof D==="string"){mf(D,{stdio:"inherit",cwd:_});return}await D(t)}async function Cs(D,t,m={},A){try{return await pf(D.hooks?.[t],D,t,m,A),!0}catch(_){return m.error?.(`${t} hook failed: ${_?.message||_}`),!1}}var pi=(D)=>D===void 0?void 0:D?"on":"off";function Gc(D){let t={ssl:D.ssl,always_use_https:pi(D.alwaysUseHttps),automatic_https_rewrites:pi(D.automaticHttpsRewrites),min_tls_version:D.minTlsVersion,tls_1_3:pi(D.tls13),brotli:pi(D.brotli),http3:pi(D.http3),"0rtt":pi(D.zeroRtt),early_hints:pi(D.earlyHints),browser_cache_ttl:D.browserCacheTtl,always_online:pi(D.alwaysOnline),websockets:pi(D.websockets),email_obfuscation:pi(D.emailObfuscation)};if(D.hsts)t.security_header={strict_transport_security:{enabled:D.hsts.enabled,max_age:D.hsts.maxAge??31536000,include_subdomains:D.hsts.includeSubdomains??!1,preload:D.hsts.preload??!1,nosniff:D.hsts.noSniff??!0}};for(let m of Object.keys(t))if(t[m]===void 0)delete t[m];return{...t,...D.raw??{}}}var $s={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 ff}from"node:tls";async function Kc(D){let{address:t,serverName:m,port:A=443,timeoutMs:_=5000}=D;return new Promise((z)=>{let U=!1,Y=(ne)=>{if(U)return;U=!0;try{X.destroy()}catch{}z(ne)},X=ff({host:t,port:A,servername:m,rejectUnauthorized:!1,timeout:_});X.once("secureConnect",()=>{if(X.authorized){Y({reachable:!0,trusted:!0});return}Y({reachable:!0,trusted:!1,reason:X.authorizationError?String(X.authorizationError):"origin certificate is not trusted for this hostname"})}),X.once("timeout",()=>{Y({reachable:!1,trusted:!1,reason:`no TLS handshake within ${_}ms`})}),X.once("error",(ne)=>{Y({reachable:!1,trusted:!1,reason:ne.message})})})}function gf(D,t){let m=t.replace(/\.$/,"").toLowerCase();return D.some((A)=>{let _=A.replace(/\.$/,"").toLowerCase();if(_===m)return!0;if(!_.startsWith("*."))return!1;let z=_.slice(2);if(!m.endsWith(`.${z}`))return!1;return!m.slice(0,m.length-z.length-1).includes(".")})}async function Jc(D){let{provider:t,zone:m,hosts:A,ipv4:_,ipv6:z,proxied:U=!0,settings:Y=$s,cache:X,originGuard:ne,purge:re=!0,ttl:ie=300,skipOriginProbe:ae=!1,skipEdgeCertificateCheck:be=!1}=D,ke={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(A.length===0)return ke;let le=[],$e=U&&!be?await t.listEdgeCertificateHosts(m):null;for(let Se of A){let Ae=U;if(Ae&&$e&&!gf($e,Se)){Ae=!1;let ze=$e.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${$e.join(", ")})`;ke.deferredProxy.push({host:Se,reason:ze}),ke.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(Ae&&!ae){let ze=await Kc({address:_,serverName:Se});if(!ze.trusted){Ae=!1;let Ne=ze.reason||"origin is not serving a trusted certificate";ke.deferredProxy.push({host:Se,reason:Ne}),ke.warnings.push(`${Se}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${Ne}). 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(Ae)le.push(Se);let Re=[{type:"A",content:_}];if(z&&Ji(Se))Re.push({type:"AAAA",content:z});for(let{type:ze,content:Ne}of Re){let je=await t.upsertRecord(m,{name:Se,type:ze,content:Ne,ttl:ie,proxied:Ae});if(je.success)ke.records.push({host:Se,type:ze,content:Ne,proxied:Ae});else ke.warnings.push(`${Se} ${ze} → ${Ne} failed: ${je.message||"unknown provider error"}`)}}if(le.length===0){if(U)ke.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return ke}try{let Se=Gc(Y),Ae=await t.applyZoneSettings(m,Se);ke.settingsChanged=Ae.changed;for(let Re of Ae.failed)ke.warnings.push(`zone setting '${Re.id}' could not be applied: ${Re.error}`)}catch(Se){ke.warnings.push(`zone settings could not be read: ${Se instanceof Error?Se.message:String(Se)}`)}let Pe=_s(le,X);if(Pe.length>0){let Se=await t.putManagedPhaseRules(m,"http_request_cache_settings",Pe);if(Se.success)ke.cacheRules=Pe.length;else ke.warnings.push(`cache rules could not be written: ${Se.message}`)}if(ne){let Se=Os(le,ne.header,ne.value);if(Se.length>0){let Ae=await t.putManagedPhaseRules(m,"http_request_late_transform",Se);if(Ae.success)ke.originGuard=!0;else ke.warnings.push(`origin guard header could not be written: ${Ae.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(re){if(ke.purged=await t.purgeCache(m,{hosts:le}),!ke.purged)ke.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return ke}var hf=(D)=>process.env[D];function qd(D,t){let m=D.replace(/\.$/,"").toLowerCase();if(t){let A=t.replace(/\.$/,"").toLowerCase();if(m===A||m.endsWith(`.${A}`))return A}return m.split(".").slice(-2).join(".")}function Yc(D,t={}){let m=t.env??hf,A=D.infrastructure?.compute?.proxy?.cdn,_=[];if(!A||A.provider!=="cloudflare")return{plan:null,errors:_};if(A.originDomain)_.push(`compute.proxy.cdn.originDomain (${A.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 z=m("CLOUDFLARE_API_TOKEN");if(!z)return _.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:_};let U=D.sites??{},Y=A.frontedHosts?.length?[...new Set(A.frontedHosts.map((ae)=>ae.toLowerCase()))]:Yi(U,{autoWww:D.infrastructure?.compute?.proxy?.autoWww!==!1});if(Y.length===0)return _.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:_};let X=D.infrastructure?.dns?.domain,ne=new Set(Y.map((ae)=>qd(ae,X)));if(ne.size>1)return _.push(`Fronted hosts span more than one zone (${[...ne].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:_};let re=A.cloudflare??{},ie=A.secret?{header:A.secretHeader??"X-Origin-Verify",value:A.secret}:void 0;return{plan:{zone:[...ne][0],hosts:Y,apiToken:z,zoneId:re.zoneId??m("CLOUDFLARE_ZONE_ID"),accountId:re.accountId??m("CLOUDFLARE_ACCOUNT_ID"),proxied:re.proxied!==!1,settings:re.settings??$s,cache:re.cache,originGuard:ie,purge:re.purgeOnDeploy!==!1,skipOriginProbe:re.skipOriginProbe===!0},errors:_}}var yf="https://api.cloudflare.com/client/v4",Hd=10042,vf=10006,bf=10059;class ho extends Error{status;errors;constructor(D,t,m=[]){super(D);this.name="R2ApiError",this.status=t,this.errors=m}hasCode(D){return this.errors.some((t)=>t.code===D)}}class Ui extends ho{accountId;constructor(D,t,m=[]){super(`R2 is not enabled on Cloudflare account ${D}. 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=D}}class jo{name="cloudflare-r2";apiToken;accountId;fetchImpl;constructor(D){if(!D.apiToken)throw Error("Cloudflare R2 needs an API token");if(!D.accountId)throw Error("Cloudflare R2 needs an account id");this.apiToken=D.apiToken,this.accountId=D.accountId,this.fetchImpl=D.fetch??((t,m)=>fetch(t,m))}async requestEnvelope(D,t,m,A={}){let _={Authorization:`Bearer ${this.apiToken}`};if(m!==void 0)_["Content-Type"]="application/json";if(A.jurisdiction&&A.jurisdiction!=="default")_["cf-r2-jurisdiction"]=A.jurisdiction;let z=await this.fetchImpl(`${yf}/accounts/${this.accountId}/r2${t}`,{method:D,headers:_,body:m===void 0?void 0:JSON.stringify(m)}),U=await z.text(),Y;try{Y=JSON.parse(U)}catch{throw new ho(`Cloudflare R2 API returned ${z.status} with a non-JSON body: ${U.slice(0,200)}`,z.status)}if(!Y.success){let X=Y.errors??[];if(X.some((re)=>re.code===Hd))throw new Ui(this.accountId,z.status,X);let ne=X.map((re)=>`${re.code}: ${re.message}`).join(", ");throw new ho(`Cloudflare R2 API error (${z.status}) on ${D} ${t}: ${ne||U.slice(0,200)}`,z.status,X)}return Y}async request(D,t,m,A){return(await this.requestEnvelope(D,t,m,A)).result}bucketPath(D){return`/buckets/${encodeURIComponent(D)}`}async listBuckets(D={}){let t=[],m;do{let A=new URLSearchParams({per_page:"1000"});if(m)A.set("cursor",m);let _=await this.requestEnvelope("GET",`/buckets?${A}`,void 0,D),z=_.result?.buckets??[];t.push(...z),m=z.length>0?_.result_info?.cursor||void 0:void 0}while(m);return t}async getBucket(D,t={}){try{return await this.request("GET",this.bucketPath(D),void 0,t)}catch(m){if(m instanceof Ui)throw m;if(m instanceof ho&&(m.hasCode(vf)||m.status===404))return null;throw m}}async ensureBucket(D,t={}){let m={jurisdiction:t.jurisdiction},A=await this.getBucket(D,m);if(A)return{bucket:A,created:!1};let _={name:D};if(t.locationHint)_.locationHint=t.locationHint;let z=await this.request("POST","/buckets",_,m);return{bucket:{...z,name:z?.name||D},created:!0}}async getCors(D,t={}){try{return(await this.request("GET",`${this.bucketPath(D)}/cors`,void 0,t))?.rules??[]}catch(m){if(m instanceof ho&&!(m instanceof Ui)&&(m.hasCode(bf)||m.status===404))return[];throw m}}async putCors(D,t,m={}){if(t.length===0){await this.request("DELETE",`${this.bucketPath(D)}/cors`,void 0,m);return}await this.request("PUT",`${this.bucketPath(D)}/cors`,{rules:t},m)}async ensureCors(D,t,m={}){let A=await this.getCors(D,m);if(oa(A,t))return!1;return await this.putCors(D,t,m),!0}async getLifecycle(D,t={}){return(await this.request("GET",`${this.bucketPath(D)}/lifecycle`,void 0,t))?.rules??[]}async putLifecycle(D,t,m={}){await this.request("PUT",`${this.bucketPath(D)}/lifecycle`,{rules:t},m)}async ensureLifecycle(D,t,m={}){let A=await this.getLifecycle(D,m);if(sa(A,t))return!1;return await this.putLifecycle(D,t,m),!0}async listCustomDomains(D,t={}){return(await this.request("GET",`${this.bucketPath(D)}/domains/custom`,void 0,t))?.domains??[]}async attachCustomDomain(D,t,m={}){return this.request("POST",`${this.bucketPath(D)}/domains/custom`,{domain:t.domain,zoneId:t.zoneId,enabled:t.enabled??!0,minTLS:t.minTLS??"1.2"},m)}async updateCustomDomain(D,t,m,A={}){return this.request("PUT",`${this.bucketPath(D)}/domains/custom/${encodeURIComponent(t)}`,m,A)}async ensureCustomDomain(D,t,m={},A){let _=t.minTLS??"1.2",U=(A??await this.listCustomDomains(D,m)).find((ne)=>ne.domain.toLowerCase()===t.domain.toLowerCase());if(!U){let ne=await this.attachCustomDomain(D,{...t,minTLS:_,enabled:!0},m);return{action:"attached",domain:{...ne,domain:ne?.domain||t.domain}}}let Y=U.minTLS??"1.0";if(U.enabled&&Y===_)return{action:"unchanged",domain:U};let X=await this.updateCustomDomain(D,U.domain,{enabled:!0,minTLS:_},m);return{action:"updated",domain:{...U,...X}}}async getManagedDomain(D,t={}){return this.request("GET",`${this.bucketPath(D)}/domains/managed`,void 0,t)}async setManagedDomain(D,t,m={}){let A=await this.getManagedDomain(D,m);if(A?.enabled===t)return{changed:!1,domain:A};return{changed:!0,domain:await this.request("PUT",`${this.bucketPath(D)}/domains/managed`,{enabled:t},m)}}}function As(D){if(Array.isArray(D))return`[${D.map(As).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${As(A)}`).join(",")}}`;return JSON.stringify(D)}function Gd(D,t){let m=(A)=>A&&A.length>0?[...A].map(String).sort():void 0;return{id:t?D.id:void 0,allowed:{origins:m(D.allowed?.origins),methods:m(D.allowed?.methods?.map((A)=>A.toUpperCase())),headers:m(D.allowed?.headers?.map((A)=>A.toLowerCase()))},exposeHeaders:m(D.exposeHeaders?.map((A)=>A.toLowerCase())),maxAgeSeconds:D.maxAgeSeconds}}function oa(D,t){if(D.length!==t.length)return!1;return t.every((m,A)=>{let _=m.id!==void 0;return As(Gd(D[A],_))===As(Gd(m,_))})}function sa(D,t){if(D.length!==t.length)return!1;let m=(A)=>As([...A].map((_)=>({..._,storageClassTransitions:_.storageClassTransitions?.length?_.storageClassTransitions:void 0})).sort((_,z)=>_.id.localeCompare(z.id)));return m(D)===m(t)}var wf="r2 cache",Sf=/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;async function Xc(D,t={}){let m=t.log??(()=>{}),A={buckets:[],warnings:[]},_=D.infrastructure?.r2??D.r2,z=Object.entries(_?.buckets??{});if(z.length===0)return m("R2: no buckets declared, skipping."),A;if(!t.apiToken||!t.accountId){let re=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),ie=`R2: ${z.length} bucket(s) declared but ${re} is not set, skipping.`;return m(ie),A.warnings.push(ie),A}let U=t.dryRun===!0,Y=new jo({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),X=new he(t.apiToken,{zoneId:t.zoneId,accountId:t.accountId}),ne=new Map;for(let[re,ie]of z){let ae=ie?.name;if(!ae||!Sf.test(ae)){A.warnings.push(`R2: bucket '${re}' has an invalid name '${ae??""}' (3-63 chars: lowercase letters, digits, hyphens), skipping.`);continue}m(`R2: ${U?"checking":"reconciling"} bucket ${ae}...`);let be={name:ae,changes:[],domains:[]};if(A.buckets.push(be),await Cf(ie,{r2:Y,cloudflare:X,dryRun:U,summary:be,warnings:A.warnings,claimed:ne,log:m}),be.changes.length===0)m(`R2: ${ae} is in sync.`);else for(let ke of be.changes)m(`R2: ${ae}: ${ke}`)}return A}async function Cf(D,t){let{r2:m,dryRun:A,summary:_,warnings:z}=t,U=D.name,Y={jurisdiction:D.jurisdiction},X=(be,ke)=>{let le=A?ke&&`would ${ke}`:be;if(le)_.changes.push(le)},ne;if(A)ne=await m.getBucket(U,Y)!==null;else{let{created:be}=await m.ensureBucket(U,{locationHint:D.locationHint,jurisdiction:D.jurisdiction});if(ne=!0,be)X("created","")}if(!ne)X("","create bucket");let re=kf(D.customDomains);await Rs(t,`cors on ${U}`,async()=>{if(!D.cors)return;if(!ne){X("cors updated","set cors");return}let be=await m.getCors(U,Y);if(oa(be,D.cors))return;if(!A)await m.putCors(U,D.cors,Y);X(D.cors.length===0?"cors removed":"cors updated",D.cors.length===0?"remove cors":"update cors")}),await Rs(t,`lifecycle on ${U}`,async()=>{if(!D.lifecycle)return;let be=D.lifecycle.map(Yd);if(ne){let ke=await m.getLifecycle(U,Y);if(sa(ke,be))return}if(!A)await m.putLifecycle(U,be,Y);X("lifecycle updated","update lifecycle")}),await Rs(t,`r2.dev URL on ${U}`,async()=>{let be=D.publicDevUrl===!0;if(!ne){if(be)X("r2.dev URL enabled","enable r2.dev URL");return}if((await m.getManagedDomain(U,Y))?.enabled===be)return;if(!A)await m.setManagedDomain(U,be,Y);X(be?"r2.dev URL enabled":"r2.dev URL disabled",be?"enable r2.dev URL":"disable r2.dev URL")});let ie=[];if(re.length>0&&ne)try{ie=await m.listCustomDomains(U,Y)}catch(be){if(be instanceof Ui)throw be;z.push(`R2: could not list custom domains on ${U}: ${el(be)}`)}let ae=new Map;for(let{domain:be,minTLS:ke}of re){let le=t.claimed.get(be);if(le&&le!==U){z.push(`R2: ${be} is declared on both ${le} and ${U}; leaving it on ${le}.`);continue}t.claimed.set(be,U);let $e=ie.find((Se)=>Se.domain.toLowerCase()===be),Pe=ke??"1.2";if($e&&$e.enabled&&($e.minTLS??"1.0")===Pe){if(_.domains.push({domain:be,status:Qc($e)}),$e.zoneId)ae.set(be,$e.zoneId);continue}await Rs(t,`custom domain ${be} on ${U}`,async()=>{if($e){if(!A)await m.updateCustomDomain(U,$e.domain,{enabled:!0,minTLS:Pe},Y);if(X(`custom domain ${be} updated`,`update custom domain ${be}`),_.domains.push({domain:be,status:Qc({...$e,enabled:!0})}),$e.zoneId)ae.set(be,$e.zoneId);return}let Se=await t.cloudflare.zoneIdFor(be);if(ae.set(be,Se),!A)await m.ensureCustomDomain(U,{domain:be,zoneId:Se,minTLS:Pe},Y,ie);X(`custom domain ${be} attached`,`attach custom domain ${be}`),_.domains.push({domain:be,status:A?"not attached":"pending"})},()=>_.domains.push({domain:be,status:"error"}))}if(D.cache&&re.length>0)await $f(D,re.map((be)=>be.domain).filter((be)=>t.claimed.get(be)===U),ae,t,X)}async function $f(D,t,m,A,_){let z=Kd(D.cache);if(!z||t.length===0)return;let U=new Map;for(let Y of t){let X=m.get(Y);if(!X)try{X=await A.cloudflare.zoneIdFor(Y)}catch(ne){A.warnings.push(`R2: could not resolve the zone for ${Y}, cache rule skipped: ${el(ne)}`);continue}U.set(X,[...U.get(X)??[],Y])}for(let Y of U.values()){let X={action:"set_cache_settings",description:`${Ar} ${wf}`,expression:`(${wr(Y)})`,enabled:!0,action_parameters:z};await Rs(A,`cache rule for ${Y.join(", ")}`,async()=>{let ne=await A.cloudflare.getPhaseRules(Y[0],"http_request_cache_settings");if(Jd(ne,X))return;if(!A.dryRun){let re=await A.cloudflare.putManagedPhaseRules(Y[0],"http_request_cache_settings",[X]);if(!re.success)throw Error(re.message||"cache rule write failed")}_(`cache rule updated for ${Y.join(", ")}`,`update cache rule for ${Y.join(", ")}`)})}}function Kd(D){if(D.edgeTtl===void 0&&D.browserTtl===void 0)return null;let t={cache:!0};if(D.edgeTtl!==void 0)t.edge_ttl={mode:"override_origin",default:D.edgeTtl};if(D.browserTtl!==void 0)t.browser_ttl={mode:"override_origin",default:D.browserTtl};return t}function Jd(D,t){let m=Rr(t.expression),A=wi(t.expression),_=(Y)=>(Y.description||"").startsWith(Ar),z=(Y)=>Y.action===t.action&&Y.description===t.description&&(Y.enabled??!0)===(t.enabled??!0)&&wi(Y.expression)===A&&aa(Y.action_parameters)===aa(t.action_parameters),U=!1;for(let Y of D){if(!_(Y))continue;let X=Rr(Y.expression);if(!m.some((re)=>X.includes(re)))continue;if(z(Y)&&m.every((re)=>X.includes(re))&&!U){U=!0;continue}return!1}return U}function Yd(D){let t={id:D.id,enabled:D.enabled??!0,conditions:{prefix:D.prefix??""}};if(D.expireAfterDays!==void 0)t.deleteObjectsTransition={condition:{type:"Age",maxAge:Zc(D.expireAfterDays)}};else if(D.expireOn!==void 0)t.deleteObjectsTransition={condition:{type:"Date",date:D.expireOn}};if(D.abortMultipartUploadsAfterDays!==void 0)t.abortMultipartUploadsTransition={condition:{type:"Age",maxAge:Zc(D.abortMultipartUploadsAfterDays)}};if(D.infrequentAccessAfterDays!==void 0)t.storageClassTransitions=[{storageClass:"InfrequentAccess",condition:{type:"Age",maxAge:Zc(D.infrequentAccessAfterDays)}}];return t}function Zc(D){return Math.round(D*86400)}function kf(D){let t=new Set,m=[];for(let A of D??[]){let _=typeof A==="string"?{domain:A}:A,z=_.domain?.trim().replace(/\.$/,"").toLowerCase();if(!z||t.has(z))continue;t.add(z),m.push({domain:z,minTLS:_.minTLS})}return m}function Qc(D){if(!D.enabled)return"disabled";let t=D.status?.ownership,m=D.status?.ssl;if(t==="active"&&m==="active")return"active";for(let A of[t,m])if(A==="error"||A==="blocked"||A==="deactivated")return A;return"pending"}async function Rs(D,t,m,A){try{await m()}catch(_){if(_ instanceof Ui)throw _;D.warnings.push(`R2: ${t} failed: ${el(_)}`),A?.()}}function el(D){return D instanceof Error?D.message:String(D)}function aa(D){if(Array.isArray(D))return`[${D.map(aa).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${aa(A)}`).join(",")}}`;return JSON.stringify(D)}import{basename as Ef,extname as Tf}from"node:path";import{createHash as Af}from"node:crypto";var Rf="https://api.cloudflare.com/client/v4",Vi="TS_CLOUD_CONTENT_HASH",Is="2025-09-01",nl="application/javascript+module",If=10007,Pf=[1e4,9109];class Bo extends Error{status;errors;constructor(D,t,m=[]){super(D);this.name="WorkersApiError",this.status=t,this.errors=m}hasCode(D){return this.errors.some((t)=>t.code===D)}}class ca extends Bo{permission;constructor(D,t,m,A=[]){super(`The Cloudflare API token is missing the "${D}" permission (${t}). Edit the token in the Cloudflare dashboard (My Profile, API Tokens), add it, then re-run the deploy.`,m,A);this.name="WorkersPermissionError",this.permission=D}}class da{name="cloudflare-workers";apiToken;accountId;fetchImpl;constructor(D){if(!D.apiToken)throw Error("Cloudflare Workers needs an API token");if(!D.accountId)throw Error("Cloudflare Workers needs an account id");this.apiToken=D.apiToken,this.accountId=D.accountId,this.fetchImpl=D.fetch??((t,m)=>fetch(t,m))}async request(D,t,m){let A={Authorization:`Bearer ${this.apiToken}`},_;if(m instanceof FormData)_=m;else if(m!==void 0)A["Content-Type"]="application/json",_=JSON.stringify(m);let z=await this.fetchImpl(`${Rf}/accounts/${this.accountId}/workers${t}`,{method:D,headers:A,body:_}),U=await z.text(),Y;try{Y=JSON.parse(U)}catch{throw new Bo(`Cloudflare Workers API returned ${z.status} with a non-JSON body: ${U.slice(0,200)}`,z.status)}if(!Y.success){let X=Y.errors??[],ne=X.map((re)=>`${re.code}: ${re.message}`).join(", ");if(Df(z.status,X))throw new ca(xf(t),`${D} ${t} -> ${z.status}${ne?`, ${ne}`:""}`,z.status,X);throw new Bo(`Cloudflare Workers API error (${z.status}) on ${D} ${t}: ${ne||U.slice(0,200)}`,z.status,X)}return Y.result}scriptPath(D){return`/scripts/${encodeURIComponent(D)}`}async getSettings(D){try{return await this.request("GET",`${this.scriptPath(D)}/settings`)}catch(t){if(t instanceof ca)throw t;if(t instanceof Bo&&(t.hasCode(If)||t.status===404))return null;throw t}}async getScript(D){return this.getSettings(D)}async uploadModuleScript(D,t){return this.request("PUT",this.scriptPath(D),Qd(t))}async ensureModuleScript(D,t){let m=Ps(t),A=await this.getSettings(D);if(A&&fa(A,t,m))return{action:"unchanged",hash:m};return await this.uploadModuleScript(D,Xd(t,m)),{action:A?"updated":"created",hash:m}}async listCustomDomains(D={}){let t=new URLSearchParams;if(D.service)t.set("service",D.service);if(D.hostname)t.set("hostname",D.hostname);if(D.zoneId)t.set("zone_id",D.zoneId);let m=t.toString(),A=m?`?${m}`:"";return await this.request("GET",`/domains${A}`)??[]}async attachCustomDomain(D,t){let m={hostname:D,service:t.service,environment:t.environment??"production"};if(t.zoneId)m.zone_id=t.zoneId;return this.request("PUT","/domains",m)}async detachCustomDomain(D){await this.request("DELETE",`/domains/${encodeURIComponent(D)}`)}async ensureCustomDomain(D,t,m){let _=(m??await this.listCustomDomains({hostname:D})).find((U)=>U.hostname.toLowerCase()===D.toLowerCase());if(_&&_.service===t.service)return{action:"unchanged",domain:_};if(_)throw Error(`${D} is attached to the Worker '${_.service}'. Detach it there first (Workers & Pages, ${_.service}, Settings, Domains & Routes); ts-cloud does not move it.`);let z=await this.attachCustomDomain(D,t);return{action:"attached",domain:{...z,hostname:z?.hostname||D}}}}function Df(D,t){if(t.some((m)=>Pf.includes(m.code)))return!0;return(D===401||D===403)&&t.length===0}function xf(D){if(D.startsWith("/domains"))return"Workers Routes: Edit (zone, for Workers custom domains) and Workers Scripts: Edit (account)";return"Workers Scripts: Edit (account)"}function Qd(D){if(!D.modules.some((A)=>A.name===D.mainModule))throw Error(`Worker main module '${D.mainModule}' is not one of the uploaded modules`);let t={main_module:D.mainModule,bindings:D.bindings??[],compatibility_date:D.compatibilityDate??Is,compatibility_flags:D.compatibilityFlags??[],keep_bindings:["secret_text"]},m=new FormData;m.append("metadata",JSON.stringify(t));for(let A of D.modules)m.append(A.name,new Blob([A.content],{type:A.type}),A.name);return m}function Ps(D){let t={mainModule:D.mainModule,modules:[...D.modules].sort((m,A)=>m.name.localeCompare(A.name)).map((m)=>({name:m.name,type:m.type,sha256:Zd(m.content)})),bindings:[...D.bindings??[]].filter((m)=>m.name!==Vi).sort((m,A)=>m.name.localeCompare(A.name)),compatibilityDate:D.compatibilityDate??Is,compatibilityFlags:[...D.compatibilityFlags??[]].sort()};return Zd(tl(t))}function Xd(D,t=Ps(D)){return{...D,bindings:[...(D.bindings??[]).filter((m)=>m.name!==Vi),{type:"plain_text",name:Vi,text:t}]}}function fa(D,t,m){let A=D.bindings??[],_=A.find((z)=>z.name===Vi&&z.type==="plain_text");if(!_||_.text!==m)return!1;return(t.bindings??[]).every((z)=>{let U=A.find((X)=>X.name===z.name);if(!U||U.type!==z.type)return!1;let Y=z.type==="r2_bucket"?"bucket_name":z.type==="plain_text"?"text":void 0;return!Y||U[Y]===z[Y]})}function Zd(D){return Af("sha256").update(D).digest("hex")}function tl(D){if(Array.isArray(D))return`[${D.map(tl).join(",")}]`;if(D&&typeof D==="object")return`{${Object.entries(D).filter(([,m])=>m!==void 0).sort(([m],[A])=>m.localeCompare(A)).map(([m,A])=>`${JSON.stringify(m)}:${tl(A)}`).join(",")}}`;return JSON.stringify(D)}async function rl(D){if(!await Bun.file(D).exists())throw Error(`Worker entry not found: ${D}`);let t;try{t=await Bun.build({entrypoints:[D],target:"browser",format:"esm",minify:!0,external:["cloudflare:*"]})}catch(_){throw Error(`Bundling Worker ${D} failed: ${Nf(_)}`)}if(!t.success)throw Error(`Bundling Worker ${D} failed: ${t.logs.map((_)=>String(_.message??_)).join("; ")}`);if(t.outputs.length!==1)throw Error(`Bundling Worker ${D} produced ${t.outputs.length} files (${t.outputs.map((_)=>_.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 ${D} produced a ${m.kind} instead of an entry module`);let A=await m.text();return{name:`${Ef(D,Tf(D))}.js`,content:A,type:nl,size:new TextEncoder().encode(A).byteLength}}function Nf(D){if(D instanceof AggregateError&&D.errors.length>0)return D.errors.map((t)=>t instanceof Error?t.message:String(t?.message??t)).join("; ");return D instanceof Error?D.message:String(D)}import{isAbsolute as Of,resolve as Lf}from"node:path";var Ff="https://api.cloudflare.com/client/v4",jf=/^[a-z0-9][a-z0-9_-]{0,62}$/;async function il(D,t={}){let m=t.log??(()=>{}),A={workers:[],warnings:[]},_=Object.entries(D.infrastructure?.workers??D.workers??{});if(_.length===0)return m("Workers: none declared, skipping."),A;if(!t.apiToken||!t.accountId){let Y=[!t.apiToken&&"CLOUDFLARE_API_TOKEN",!t.accountId&&"CLOUDFLARE_ACCOUNT_ID"].filter(Boolean).join(" and "),X=`Workers: ${_.length} Worker(s) declared but ${Y} is not set, skipping.`;return m(X),A.warnings.push(X),A}let z=D.infrastructure?.r2??D.r2,U={workers:new da({apiToken:t.apiToken,accountId:t.accountId,fetch:t.fetch}),r2:new jo({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,X)=>fetch(Y,X)),projectRoot:t.projectRoot??process.cwd(),dryRun:t.dryRun===!0,warnings:A.warnings,log:m,r2ConfigDomains:Wf(z),r2Buckets:z,claimed:new Map};for(let[Y,X]of _){let ne=X?.name;if(!ne||!jf.test(ne)){A.warnings.push(`Workers: '${Y}' has an invalid name '${ne??""}' (1-63 chars: lowercase letters, digits, '-' and '_'), skipping.`);continue}if(!X.entry){A.warnings.push(`Workers: ${ne} has no entry, skipping.`);continue}m(`Workers: ${U.dryRun?"checking":"reconciling"} ${ne}...`);let re={name:ne,changes:[],domains:[]};A.workers.push(re),await Bf(X,re,U);for(let ie of re.changes)m(`Workers: ${ne}: ${ie}`)}return A}async function Bf(D,t,m){let A=D.name,_=Of(D.entry)?D.entry:Lf(m.projectRoot,D.entry),z;try{z=await rl(_)}catch(Y){throw Error(`Worker ${A}: ${_o(Y)}`)}t.changes.push(`bundled ${qf(z.size)}`);let U={mainModule:z.name,modules:[{name:z.name,content:z.content,type:z.type}],bindings:eu(D,m),compatibilityDate:D.compatibilityDate??Is,compatibilityFlags:D.compatibilityFlags??[]};if(m.dryRun){let Y=await m.workers.getSettings(A);t.changes.push(Y&&fa(Y,U,Ps(U))?"unchanged":"would upload")}else{let{action:Y}=await m.workers.ensureModuleScript(A,U);t.changes.push(Y==="unchanged"?"unchanged":"uploaded")}for(let Y of Vf(D.customDomains))await _f(A,Y,t,m)}async function _f(D,t,m,A){let _=(be)=>{m.domains.push({domain:t,status:be})},z=(be)=>{A.warnings.push(`Workers: ${be}`),_("conflict")},U=A.claimed.get(t);if(U&&U!==D){z(`${t} is declared on both ${U} and ${D}; leaving it on ${U}.`);return}A.claimed.set(t,D);let Y=A.r2ConfigDomains.get(t);if(Y){z(`${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 X=await Mf(A);if(X===null){_("error");return}let ne=X.find((be)=>be.hostname.toLowerCase()===t);if(ne?.service===D){_("active");return}if(ne){z(`${t} is attached to the Worker '${ne.service}'. Detach it there first (Workers & Pages, ${ne.service}, Settings, Domains & Routes); it is not moved automatically.`);return}let re=(await zf(A))?.get(t);if(re){z(`${t} is attached to the R2 bucket '${re}' as a custom domain. Detach it first (R2, ${re}, 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 A.cloudflare.zoneIdFor(t)}catch(be){A.warnings.push(`Workers: could not resolve the zone for ${t}, not attached: ${_o(be)}`),_("error");return}let ae=await Uf(A,ie,t);if(ae.length>0){let be=ae.map((ke)=>`${ke.type} ${ke.content}`).join(", ");z(`${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(A.dryRun){m.changes.push(`would attach custom domain ${t}`),_("not attached");return}try{await A.workers.ensureCustomDomain(t,{service:D,zoneId:ie},X),m.changes.push(`custom domain ${t} attached`),X.push({id:"",hostname:t,service:D,zone_id:ie}),_("pending")}catch(be){A.warnings.push(`Workers: custom domain ${t} on ${D} failed: ${_o(be)}`),_("error")}}async function Mf(D){if(D.attached!==void 0)return D.attached;try{D.attached=await D.workers.listCustomDomains()}catch(t){D.warnings.push(`Workers: could not list Worker custom domains, none attached: ${_o(t)}`),D.attached=null}return D.attached}async function zf(D){if(D.r2AccountDomains!==void 0)return D.r2AccountDomains;let t=new Map;try{let m=(await D.r2.listBuckets()).map((A)=>({name:A.name}));for(let A of Object.values(D.r2Buckets?.buckets??{}))if(A.jurisdiction&&A.jurisdiction!=="default")m.push({name:A.name,jurisdiction:A.jurisdiction});for(let A of m){let _=await D.r2.listCustomDomains(A.name,{jurisdiction:A.jurisdiction}).catch(()=>[]);for(let z of _)t.set(z.domain.toLowerCase(),A.name)}D.r2AccountDomains=t}catch(m){D.log(`Workers: could not check R2 custom domains (${_o(m)}); relying on the DNS check.`),D.r2AccountDomains=null}return D.r2AccountDomains}async function Uf(D,t,m){try{let A=await D.fetch(`${Ff}/zones/${t}/dns_records?name=${encodeURIComponent(m)}&per_page=100`,{method:"GET",headers:{Authorization:`Bearer ${D.apiToken}`}}),_=await A.json();if(!_?.success)throw Error(`HTTP ${A.status}`);return(_.result??[]).filter((z)=>z.name?.toLowerCase()===m).map((z)=>({type:z.type??"?",content:z.content??""}))}catch(A){return D.log(`Workers: could not read DNS records for ${m} (${_o(A)}); attaching anyway.`),[]}}function eu(D,t){let m=[],A=new Set,_=(U)=>{if(U===Vi)return t.warnings.push(`Workers: ${D.name}: binding name ${Vi} is reserved for ts-cloud, ignored.`),!1;if(A.has(U))return t.warnings.push(`Workers: ${D.name}: binding ${U} is declared twice; the first one wins.`),!1;return A.add(U),!0},z=new Map;for(let U of Object.values(t.r2Buckets?.buckets??{}))if(U.jurisdiction&&U.jurisdiction!=="default")z.set(U.name,U.jurisdiction);for(let[U,Y]of Object.entries(D.bindings?.r2Buckets??{})){if(!_(U))continue;let X=z.get(Y);m.push(X?{type:"r2_bucket",name:U,bucket_name:Y,jurisdiction:X}:{type:"r2_bucket",name:U,bucket_name:Y})}for(let[U,Y]of Object.entries(D.bindings?.vars??{}))if(_(U))m.push({type:"plain_text",name:U,text:String(Y)});return m}function Wf(D){let t=new Map;for(let m of Object.values(D?.buckets??{}))for(let A of m?.customDomains??[]){let _=tu(typeof A==="string"?A:A.domain);if(_)t.set(_,m.name)}return t}function Vf(D){return[...new Set((D??[]).map(tu).filter(Boolean))]}function tu(D){return(D??"").trim().replace(/\.$/,"").toLowerCase()}function qf(D){if(D<1024)return`${D} B`;if(D<1048576)return`${(D/1024).toFixed(1)} KB`;return`${(D/1024/1024).toFixed(1)} MB`}function _o(D){return D instanceof Error?D.message:String(D)}async function Yf(D){let t=ia();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 A=await new ut(D).getCallerIdentity();if(A.Arn)e(`AWS identity: ${A.Arn}`)}catch(m){a(`Could not verify AWS identity: ${m.message}`)}}function Zf(){try{return cl("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function ol(D,t,m,A){let{ensureManagementDashboard:_}=await import("./chunk-zywk12mp.js");_(D,{logger:{info:e,warn:a}});let z=D.sites||{},U=Object.entries(z);if(U.length===0)return a("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(A&&!z[A])return r(`Site '${A}' was not found. Configured sites: ${U.map(([Pe])=>Pe).join(", ")}`),!1;let Y=U.filter(([Pe,Se])=>{if(!Se)return!1;if(A&&Pe!==A)return!1;if(I(Se)==="bucket")return a(`Site '${Pe}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return Ks(Se)});if(A)e(`Deploying only '${A}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let X=D.project.slug,re=(D.infrastructure?.compute||{}).runtime||"bun",ie=O({config:D}),ae=Zf(),be=new Map,ke=new Map,le={step:(Pe)=>d(Pe),error:(Pe)=>r(Pe)};if(!await Cs(D,"beforeDeploy",le))return!1;if(!await Cs(D,"beforeBuild",le))return!1;for(let[Pe,Se]of Y){let Ae=I(Se);if(i(`Preparing site: ${Pe}`),e(`Domain: ${Se.domain||"(none)"}`),e(`Source: ${Se.root}`),e(`Kind: ${Ae==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),Ae==="server-app")e(`Start: ${Se.start}`),e(`Port: ${Se.port??"(unset)"}`);if(Se.build){d(`Running build: ${Se.build}`);try{cl(Se.build,{stdio:"inherit",cwd:process.cwd()})}catch(Ue){return r(`Build failed for site '${Pe}': ${Ue.message}`),!1}}let Re=Vd({root:Se.root,siteName:Pe,expectIndex:Ae==="server-static"});for(let Ue of Re)if(Ue.level==="error")r(Ue.message);else a(Ue.message);if(Re.some((Ue)=>Ue.level==="error"))return!1;let ze=Se.build?void 0:JSON.stringify([Jf(Se.root),[...Se.exclude||[]].sort()]),Ne=ze?ke.get(ze):void 0;if(Ne){d(`Reusing package for ${Se.root} → ${Ne}`),be.set(Pe,Ne);continue}let je=su(ou(),`${X}-${Pe}-${ae}.tar.gz`);d(`Packaging ${Se.root} → ${je}`);try{let Ue=(Se.exclude||[]).map((Ct)=>`--exclude=${Ct}`);Gf("tar",["czf",je,"-C",Se.root,...Ue,"."],{stdio:"inherit",env:{...process.env,COPYFILE_DISABLE:"1"}})}catch(Ue){return r(`Failed to package '${Pe}': ${Ue.message}`),!1}if(be.set(Pe,je),ze)ke.set(ze,je)}if(!await Cs(D,"afterBuild",le))return!1;let $e=await io({config:A?{...D,sites:Object.fromEntries(Y)}:D,rpxConfig:A?D:void 0,environment:t,driver:ie,sha:ae,runtime:re,tarballForSite:(Pe)=>{let Se=be.get(Pe);if(!Se)throw Error(`Missing tarball for site '${Pe}'`);return Se},logger:{info:(Pe)=>e(Pe),warn:(Pe)=>a(Pe),error:(Pe)=>r(Pe),step:(Pe)=>d(Pe),success:(Pe)=>n(Pe)}});if($e&&!await Cs(D,"afterDeploy",le))return!1;return $e}async function ga(D){let t=new Jr;if(d("Running pre-deployment security scan..."),D.exclude?.length)e(`Excluding from the scan: ${D.exclude.join(", ")}`);let m=await t.scan({directory:D.sourceDir,failOnSeverity:D.failOnSeverity||"critical",skipPatterns:D.skipPatterns,exclude:D.exclude});return{passed:m.passed,result:m}}function Qf(){let D=su(ou(),`ts-cloud-empty-scan-${process.pid}`);return iu(D,{recursive:!0}),D}function ha(D){let{summary:t,findings:m,scannedFiles:A,duration:_}=D;if(e(`
376
376
  Scanned ${A} files in ${_}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 z=m.filter((re)=>re.pattern.severity==="critical"),U=m.filter((re)=>re.pattern.severity==="high"),Y=m.filter((re)=>re.pattern.severity==="medium"),X=m.filter((re)=>re.pattern.severity==="low"),ne=(re,ie,ae)=>{if(re.length>0){console.log(`
378
378
  ${zt(`[${ie}]`,ae)}`);for(let be of re.slice(0,10))e(` ${be.pattern.name}`),e(` File: ${be.file}:${be.line}`),e(` Match: ${be.match}`);if(re.length>10)e(` ... and ${re.length-10} more ${ie.toLowerCase()} findings`)}};ne(z,"CRITICAL","red"),ne(U,"HIGH","yellow"),ne(Y,"MEDIUM","blue"),ne(X,"LOW","gray")}}function au(D,t){let m=Object.keys(D.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 sl(D,t,m){let A=au(D,t),_=y(process.cwd(),D);try{let z=new Ot(_.store);ni(_);let U=ue(_,A);if(m)lc(z,U,m);else dc(z,U);let Y=lr(z,{scope:U,desiredConfigHash:_.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{_.store.close()}}async function Xf(D,t){let m=au(D),A=y(process.cwd(),D);try{let _=new Ot(A.store);ni(A);let z=ue(A,m),U=t.imageSha256?`${t.imageRef}@sha256:${t.imageSha256.replace(/^sha256:/,"")}`:t.imageRef;d("Scanning the built image and producing release security artifacts...");let Y=await uc(_,{scope:z,releaseId:U,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 X=lr(_,{scope:z,operationId:t.invocationId,desiredConfigHash:A.project.desiredConfigHash});return e(`Release policy: ${X.decision.policyId} v${X.decision.policyVersion} — ${X.decision.outcome.toUpperCase()}`),e(`Release decision: ${X.decision.explanation}`),{allowed:X.decision.outcome!=="block",explanation:X.decision.explanation}}finally{A.store.close()}}function eg(D){try{let t=y(process.cwd(),D),m=new er(t.store).current();if(!m.attackMode&&!m.mitigationPause&&m.ipRules.allow.length===0&&m.ipRules.block.length===0)return D;let A=rs(D,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":""}`),A}catch{return D}}function ll(D){D.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||".",A=t?.failOn||"critical",_=t?.skipPatterns?.split(",").map((Y)=>Y.trim())||[];if(!bn(m)){r(`Source directory not found: ${m}`);return}e(`Source: ${m}`),e(`Fail on: ${A} or higher severity`);let{passed:z,result:U}=await ga({sourceDir:m,failOnSeverity:A,skipPatterns:_});if(ha(U),z)n(`
@@ -382,9 +382,9 @@ Recommendations:`),e(" 1. Remove any hardcoded credentials from your code"),e("
382
382
  ✗ Deployment configuration is invalid:`);for(let ot of Y)r(` • ${ot}`);process.exitCode=1;return}if(t?.dryRun){if(t.site&&!U.sites?.[t.site]){r(`Site '${t.site}' was not found. Configured sites: ${Object.keys(U.sites||{}).join(", ")||"none"}`),process.exitCode=1;return}let ot=H(U),Rt=t.stack||T(U,A),un=B(U),pn=U.project.region||"us-east-1",mr=t.site?[t.site]:Object.keys(U.sites||{});i("Deployment Plan"),e(`Cloud provider: ${un}`),e(`Mode: ${ot}`),e(`Stack: ${Rt}`),e(`Region: ${pn}`),e(`Environment: ${A}`),e(`Sites: ${mr.length>0?mr.join(", "):"none"}`),await nu(U,{dryRun:!0}),await ru(U,{dryRun:!0}),n("Dry run complete. No infrastructure, DNS, certificates, or application files were changed.");return}if(B(U)==="aws"){let ot=U.project?.region||"us-east-1";await Yf(ot)}let ne;if(!t?.skipSecurityScan){let ot=qc(U,t?.site);if(!ot)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:Rt}=await ga({sourceDir:ot?process.cwd():Qf(),failOnSeverity:t?.securityFailOn||"critical",exclude:U.infrastructure?.security?.scan?.exclude});ha(Rt),ne=Rt}else a(`Security scan skipped (--skip-security-scan)
383
383
  `);let re=sl(U,A,ne);if(!re.allowed){r(`
384
384
  ✗ Deployment blocked by security policy: ${re.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 nu(U)){process.exitCode=1;return}if(!await ru(U)){process.exitCode=1;return}if(H(U)==="serverless"){d("Serverless project detected: deploying the Lambda application");let{deployServerlessApp:ot}=await import("./chunk-qsfhb3x7.js");await ot(U,A,{}),n("Serverless deployment complete");return}let ie=t?.stack||T(U,A),ae=U.project.region||"us-east-1",be=U.infrastructure?.deployStack!==!1,ke=U.sites&&Object.keys(U.sites).length>0,le=U.infrastructure?.dns?.provider;if(ke&&le){if(await og(U,t?.site,le,ae,t?.skipDnsVerification,A,m),!be){if(U.infrastructure?.compute){let ot=Object.values(U.sites).map((Rt)=>Rt.domain).filter((Rt)=>!!Rt);if(ot.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ra(ot)}return}}if(!be){e("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let $e=B(U);if(e(`Cloud provider: ${$e}`),e(`Stack: ${ie}`),e(`Region: ${ae}`),e(`Environment: ${A}`),($e==="hetzner"||U.infrastructure?.compute?.mode==="server")&&xo(U)){d(`Provisioning ${$e} compute infrastructure...`);let ot=O({config:U,provider:$e});if(!ot.provisionComputeInfrastructure){r(`${$e} driver does not support compute provisioning`),process.exitCode=1;return}let Rt=await ot.provisionComputeInfrastructure({config:U,environment:A});if(n(`${$e} compute infrastructure ready`),Rt.appPublicIp)e(`App server: ${Rt.appPublicIp}`);if(Rt.appInstanceId)e(`Server ID: ${Rt.appInstanceId}`);if(!await ol(U,A,ae,t?.site))r(`App deploy to ${$e} compute reported a failure`),process.exitCode=1;else{if(n(`App deployed to ${$e} compute`),t?.skipDnsVerification)e("DNS verification and record reconciliation skipped (--skip-dns-verification)");else await ng(U,Rt.appPublicIp,le,Rt.appPublicIpv6),await rg(U,le);let pn=await oo({config:U,environment:A,driver:ot,logger:{info:e,warn:a,error:r,step:d,success:n}});if(!pn)r("App deployed, but rpx TLS certificate reconciliation failed");if(!pn)process.exitCode=1;if(!t?.skipDnsVerification)await ig(U,Rt.appPublicIp,Rt.appPublicIpv6)}return}d("Generating CloudFormation template...");let Se=new Io({config:U,environment:A});Se.generate();let Ae=Se.toJSON(),Re=JSON.parse(Ae);if(Object.keys(Re.Resources||{}).length===0){e(`No infrastructure resources to deploy for environment '${A}' — skipping stack ${ie}.`);return}d("Validating template...");let Ne=Qo(Re),je=Xo(Ae),Ue=es(Re),Ct=[...Ne.errors,...je.errors,...Ue.errors];if(Ct.length>0){r("Template validation failed:");for(let ot of Ct)r(` - ${ot.path}: ${ot.message}`);return}let At=[...Ne.warnings,...je.warnings,...Ue.warnings];if(At.length>0)for(let ot of At)a(` - ${ot.path}: ${ot.message}`);n("Template validated successfully");let rt=Object.keys(Re.Resources).length;e(`
385
+ `),!await nu(U)){process.exitCode=1;return}if(!await ru(U)){process.exitCode=1;return}if(H(U)==="serverless"){d("Serverless project detected: deploying the Lambda application");let{deployServerlessApp:ot}=await import("./chunk-9qdrv6zp.js");await ot(U,A,{}),n("Serverless deployment complete");return}let ie=t?.stack||T(U,A),ae=U.project.region||"us-east-1",be=U.infrastructure?.deployStack!==!1,ke=U.sites&&Object.keys(U.sites).length>0,le=U.infrastructure?.dns?.provider;if(ke&&le){if(await og(U,t?.site,le,ae,t?.skipDnsVerification,A,m),!be){if(U.infrastructure?.compute){let ot=Object.values(U.sites).map((Rt)=>Rt.domain).filter((Rt)=>!!Rt);if(ot.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ra(ot)}return}}if(!be){e("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let $e=B(U);if(e(`Cloud provider: ${$e}`),e(`Stack: ${ie}`),e(`Region: ${ae}`),e(`Environment: ${A}`),($e==="hetzner"||U.infrastructure?.compute?.mode==="server")&&xo(U)){d(`Provisioning ${$e} compute infrastructure...`);let ot=O({config:U,provider:$e});if(!ot.provisionComputeInfrastructure){r(`${$e} driver does not support compute provisioning`),process.exitCode=1;return}let Rt=await ot.provisionComputeInfrastructure({config:U,environment:A});if(n(`${$e} compute infrastructure ready`),Rt.appPublicIp)e(`App server: ${Rt.appPublicIp}`);if(Rt.appInstanceId)e(`Server ID: ${Rt.appInstanceId}`);if(!await ol(U,A,ae,t?.site))r(`App deploy to ${$e} compute reported a failure`),process.exitCode=1;else{if(n(`App deployed to ${$e} compute`),t?.skipDnsVerification)e("DNS verification and record reconciliation skipped (--skip-dns-verification)");else await ng(U,Rt.appPublicIp,le,Rt.appPublicIpv6),await rg(U,le);let pn=await oo({config:U,environment:A,driver:ot,logger:{info:e,warn:a,error:r,step:d,success:n}});if(!pn)r("App deployed, but rpx TLS certificate reconciliation failed");if(!pn)process.exitCode=1;if(!t?.skipDnsVerification)await ig(U,Rt.appPublicIp,Rt.appPublicIpv6)}return}d("Generating CloudFormation template...");let Se=new Io({config:U,environment:A});Se.generate();let Ae=Se.toJSON(),Re=JSON.parse(Ae);if(Object.keys(Re.Resources||{}).length===0){e(`No infrastructure resources to deploy for environment '${A}' — skipping stack ${ie}.`);return}d("Validating template...");let Ne=Qo(Re),je=Xo(Ae),Ue=es(Re),Ct=[...Ne.errors,...je.errors,...Ue.errors];if(Ct.length>0){r("Template validation failed:");for(let ot of Ct)r(` - ${ot.path}: ${ot.message}`);return}let At=[...Ne.warnings,...je.warnings,...Ue.warnings];if(At.length>0)for(let ot of At)a(` - ${ot.path}: ${ot.message}`);n("Template validated successfully");let rt=Object.keys(Re.Resources).length;e(`
386
386
  Resources to deploy: ${rt}`);let kt={};for(let ot of Object.values(Re.Resources)){let Rt=ot.Type;kt[Rt]=(kt[Rt]||0)+1}for(let[ot,Rt]of Object.entries(kt).sort((un,pn)=>pn[1]-un[1]).slice(0,5))e(` - ${ot}: ${Rt}`);if(!(m||await u(`
387
- Deploy now?`,!0))){e("Deployment cancelled");return}let Pt=new v(ae),Xe=Ta(Re);if(Xe.length>0){let{ensureFailoverReplicaBuckets:ot}=await import("./chunk-w89fyres.js");d("Ensuring failover replica buckets..."),await ot(Xe,(Rt)=>e(` ${Rt}`))}d("Checking stack status...");let Dt=!1;try{let ot=await Pt.describeStacks({stackName:ie});Dt=ot.Stacks&&ot.Stacks.length>0}catch(ot){Dt=!1}if(Dt){e("Stack exists, updating...");let ot=new s("Updating CloudFormation stack...");ot.start();try{await Pt.updateStack({stackName:ie,templateBody:Ae,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:A},{Key:"ManagedBy",Value:"ts-cloud"}]}),ot.succeed("Update initiated"),d("Waiting for stack update to complete..."),await Pt.waitForStack(ie,"stack-update-complete"),n("Stack updated successfully!")}catch(Rt){if(Rt.message.includes("No updates are to be performed"))ot.succeed("No changes detected"),e("Stack is already up to date — continuing to app deploy");else throw Rt}}else{e("Creating new stack...");let ot=new s("Creating CloudFormation stack...");ot.start(),await Pt.createStack({stackName:ie,templateBody:Ae,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:A},{Key:"ManagedBy",Value:"ts-cloud"}]}),ot.succeed("Stack creation initiated"),d("Waiting for stack creation to complete..."),await Pt.waitForStack(ie,"stack-create-complete"),n("Stack created successfully!")}let qt=await Pt.getStackOutputs(ie);if(Ee(`Deployment Complete!
387
+ Deploy now?`,!0))){e("Deployment cancelled");return}let Pt=new v(ae),Xe=Ta(Re);if(Xe.length>0){let{ensureFailoverReplicaBuckets:ot}=await import("./chunk-f578z20t.js");d("Ensuring failover replica buckets..."),await ot(Xe,(Rt)=>e(` ${Rt}`))}d("Checking stack status...");let Dt=!1;try{let ot=await Pt.describeStacks({stackName:ie});Dt=ot.Stacks&&ot.Stacks.length>0}catch(ot){Dt=!1}if(Dt){e("Stack exists, updating...");let ot=new s("Updating CloudFormation stack...");ot.start();try{await Pt.updateStack({stackName:ie,templateBody:Ae,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:A},{Key:"ManagedBy",Value:"ts-cloud"}]}),ot.succeed("Update initiated"),d("Waiting for stack update to complete..."),await Pt.waitForStack(ie,"stack-update-complete"),n("Stack updated successfully!")}catch(Rt){if(Rt.message.includes("No updates are to be performed"))ot.succeed("No changes detected"),e("Stack is already up to date — continuing to app deploy");else throw Rt}}else{e("Creating new stack...");let ot=new s("Creating CloudFormation stack...");ot.start(),await Pt.createStack({stackName:ie,templateBody:Ae,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:A},{Key:"ManagedBy",Value:"ts-cloud"}]}),ot.succeed("Stack creation initiated"),d("Waiting for stack creation to complete..."),await Pt.waitForStack(ie,"stack-create-complete"),n("Stack created successfully!")}let qt=await Pt.getStackOutputs(ie);if(Ee(`Deployment Complete!
388
388
 
389
389
  Stack: ${ie}
390
390
  Region: ${ae}
@@ -393,16 +393,16 @@ Resources: ${rt}
393
393
 
394
394
  View in console:
395
395
  https://console.aws.amazon.com/cloudformation/home?region=${ae}#/stacks/stackinfo?stackId=${encodeURIComponent(ie)}`,"green"),Object.keys(qt).length>0){e(`
396
- Stack Outputs:`);for(let[ot,Rt]of Object.entries(qt))e(` - ${ot}: ${Rt}`)}if(Xe.length>0){let{grantFailoverReplicaAccess:ot}=await import("./chunk-w89fyres.js");d("Granting the distribution read access to its failover replicas..."),await ot(Xe,qt,(Rt)=>e(` ${Rt}`))}if(U.infrastructure?.storage)for(let[ot,Rt]of Object.entries(U.infrastructure.storage)){if(!Rt.website||!Rt.root)continue;let un=qt[`${ot}BucketName`]||qt.FrontendBucketName,pn=qt[`${ot}CloudFrontDistributionId`];if(!un){a(`Could not find bucket name for storage '${ot}' — skipping file upload`);continue}if(!bn(Rt.root)){a(`Source directory not found: ${Rt.root} — skipping file upload for '${ot}'`);continue}d(`Uploading files from ${Rt.root} to s3://${un}...`);let{uploadStaticFiles:mr,invalidateCache:Fi}=await import("./chunk-dpk5r544.js"),gn=await mr({sourceDir:Rt.root,bucket:un,region:ae,onProgress:(Gt,wn,Sn)=>{if(Gt%10===0||Gt===wn)e(` ${Gt}/${wn}: ${Sn}`)}});if(gn.errors.length>0)a(`Upload completed with errors: ${gn.errors.join(", ")}`);else{let Gt=gn.skipped>0?`Uploaded ${gn.uploaded} files (${gn.skipped} unchanged)`:`Uploaded ${gn.uploaded} files`;n(Gt)}if(pn&&gn.uploaded>0){d("Invalidating CloudFront cache...");let{invalidationId:Gt}=await Fi(pn);n(`Cache invalidation created: ${Gt}`)}}if(Xe.length>0){let{seedFailoverReplicas:ot}=await import("./chunk-w89fyres.js");d("Syncing failover replicas..."),await ot(Xe,(Rt)=>e(` ${Rt}`))}if(U.infrastructure?.compute)await ol(U,A,ae,t?.site);if(U.infrastructure?.compute&&U.sites){let ot=Object.values(U.sites).map((Rt)=>Rt.domain).filter((Rt)=>!!Rt);if(ot.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ra(ot)}}catch(z){if(r(`Deployment failed: ${z.message}`),process.exitCode=1,z.stack)e(`
396
+ Stack Outputs:`);for(let[ot,Rt]of Object.entries(qt))e(` - ${ot}: ${Rt}`)}if(Xe.length>0){let{grantFailoverReplicaAccess:ot}=await import("./chunk-f578z20t.js");d("Granting the distribution read access to its failover replicas..."),await ot(Xe,qt,(Rt)=>e(` ${Rt}`))}if(U.infrastructure?.storage)for(let[ot,Rt]of Object.entries(U.infrastructure.storage)){if(!Rt.website||!Rt.root)continue;let un=qt[`${ot}BucketName`]||qt.FrontendBucketName,pn=qt[`${ot}CloudFrontDistributionId`];if(!un){a(`Could not find bucket name for storage '${ot}' — skipping file upload`);continue}if(!bn(Rt.root)){a(`Source directory not found: ${Rt.root} — skipping file upload for '${ot}'`);continue}d(`Uploading files from ${Rt.root} to s3://${un}...`);let{uploadStaticFiles:mr,invalidateCache:Fi}=await import("./chunk-dpk5r544.js"),gn=await mr({sourceDir:Rt.root,bucket:un,region:ae,onProgress:(Gt,wn,Sn)=>{if(Gt%10===0||Gt===wn)e(` ${Gt}/${wn}: ${Sn}`)}});if(gn.errors.length>0)a(`Upload completed with errors: ${gn.errors.join(", ")}`);else{let Gt=gn.skipped>0?`Uploaded ${gn.uploaded} files (${gn.skipped} unchanged)`:`Uploaded ${gn.uploaded} files`;n(Gt)}if(pn&&gn.uploaded>0){d("Invalidating CloudFront cache...");let{invalidationId:Gt}=await Fi(pn);n(`Cache invalidation created: ${Gt}`)}}if(Xe.length>0){let{seedFailoverReplicas:ot}=await import("./chunk-f578z20t.js");d("Syncing failover replicas..."),await ot(Xe,(Rt)=>e(` ${Rt}`))}if(U.infrastructure?.compute)await ol(U,A,ae,t?.site);if(U.infrastructure?.compute&&U.sites){let ot=Object.values(U.sites).map((Rt)=>Rt.domain).filter((Rt)=>!!Rt);if(ot.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ra(ot)}}catch(z){if(r(`Deployment failed: ${z.message}`),process.exitCode=1,z.stack)e(`
397
397
  Stack trace:`),console.error(z.stack)}finally{if(_)await _()}}),D.command("deploy:server","Deploy EC2 infrastructure").option("--env <environment>","Environment (production, staging, development)").option("--site <name>","Deploy specific site only (routes are still regenerated in full)").action(async(t)=>{i("Deploying Server Infrastructure");try{let m=await De(),A=t?.env||"production",_=m.project.region||"us-east-1",z=Mr(m);if(z){r(z),process.exitCode=1;return}if(!xo(m)){r("No `infrastructure.compute` configured — nothing to deploy as a server."),e("Add an EC2 compute block to cloud.config, or use `cloud deploy:serverless` for Lambda apps."),process.exitCode=1;return}if(e(`Region: ${_}`),e(`Environment: ${A}`),!await ol(m,A,_,t?.site)){process.exitCode=1;return}if(m.sites){let Y=Object.values(m.sites).map((X)=>X.domain).filter((X)=>!!X);if(Y.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ra(Y)}n(`
398
- Server deployment complete!`)}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:serverless","Deploy a serverless application (http/queue/cli Lambda functions)").option("--env <environment>","Environment (production, staging, development)").option("--skip-build","Skip local build hooks").option("--skip-hooks","Skip remote deploy hooks (e.g. migrations)").option("--redeploy","Re-activate the last build without rebuilding").action(async(t)=>{try{let m=await De(),A=t?.env||"production",_=Mr(m);if(_){r(_),process.exitCode=1;return}let{deployServerlessApp:z,redeployServerlessApp:U}=await import("./chunk-qsfhb3x7.js");if(t?.redeploy){await U(m,A);return}await z(m,A,{skipBuild:t?.skipBuild,skipDeployHooks:t?.skipHooks})}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("serverless:rollback","Roll back a serverless app to the previous build").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await De(),A=t?.env||"production",{rollbackServerlessApp:_}=await import("./chunk-qsfhb3x7.js");await _(m,A)}catch(m){r(`Rollback failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:rollback [site]","Roll a compute site back to a previous release").option("--env <environment>","Environment (production, staging, development)").option("--to <release>","Release id to roll back to (default: the previous release)").option("--dry-run","Say which release it would roll back to, and change nothing").option("--all","Every configured site, instead of one").option("--only-if-live <release>","Only roll back a site whose live release is this commit (what a failed deploy switched)").action(async(t,m)=>{i("Rolling Back Release");try{let A=await De(),_=m?.env||"production",z=m?.all?Object.keys(A.sites||{}):[t||Object.keys(A.sites||{})[0]].filter(Boolean);if(z.length===0){r("No site configured to roll back."),process.exitCode=1;return}let{rollbackComputeSite:U}=await import("./chunk-v2qk9jeb.js"),Y=O({config:A});for(let X of z){let ne=await U({driver:Y,slug:A.project.slug,environment:_,logger:f},{siteName:X,to:m?.to,dryRun:m?.dryRun,onlyIfLive:m?.onlyIfLive});for(let re of ne.perInstance||[])e(` ${X} ${re.instanceId}: ${re.output?.trim()||re.status}`);if(!ne.success)r(`Rollback of ${X} failed: ${ne.error||"unknown error"}`),process.exitCode=1}}catch(A){r(`Rollback failed: ${A.message}`),process.exitCode=1}}),D.command("deploy:history [site]","Show a compute site's deployment history").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Number of entries to show",{default:"20"}).action(async(t,m)=>{i("Deployment History");try{let A=await De(),_=m?.env||"production",z=t||Object.keys(A.sites||{})[0];if(!z){r("No site configured."),process.exitCode=1;return}let{getComputeDeployHistory:U}=await import("./chunk-v2qk9jeb.js"),Y=await U({driver:O({config:A}),slug:A.project.slug,environment:_,logger:f},{siteName:z,limit:Number.parseInt(m?.limit||"20",10)||20});if(!Y.success){r(`Could not read history: ${Y.error||"unknown error"}`),process.exitCode=1;return}for(let X of Y.perInstance||[])e(`
398
+ Server deployment complete!`)}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:serverless","Deploy a serverless application (http/queue/cli Lambda functions)").option("--env <environment>","Environment (production, staging, development)").option("--skip-build","Skip local build hooks").option("--skip-hooks","Skip remote deploy hooks (e.g. migrations)").option("--redeploy","Re-activate the last build without rebuilding").action(async(t)=>{try{let m=await De(),A=t?.env||"production",_=Mr(m);if(_){r(_),process.exitCode=1;return}let{deployServerlessApp:z,redeployServerlessApp:U}=await import("./chunk-9qdrv6zp.js");if(t?.redeploy){await U(m,A);return}await z(m,A,{skipBuild:t?.skipBuild,skipDeployHooks:t?.skipHooks})}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("serverless:rollback","Roll back a serverless app to the previous build").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await De(),A=t?.env||"production",{rollbackServerlessApp:_}=await import("./chunk-9qdrv6zp.js");await _(m,A)}catch(m){r(`Rollback failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:rollback [site]","Roll a compute site back to a previous release").option("--env <environment>","Environment (production, staging, development)").option("--to <release>","Release id to roll back to (default: the previous release)").option("--dry-run","Say which release it would roll back to, and change nothing").option("--all","Every configured site, instead of one").option("--only-if-live <release>","Only roll back a site whose live release is this commit (what a failed deploy switched)").action(async(t,m)=>{i("Rolling Back Release");try{let A=await De(),_=m?.env||"production",z=m?.all?Object.keys(A.sites||{}):[t||Object.keys(A.sites||{})[0]].filter(Boolean);if(z.length===0){r("No site configured to roll back."),process.exitCode=1;return}let{rollbackComputeSite:U}=await import("./chunk-67vf8myy.js"),Y=O({config:A});for(let X of z){let ne=await U({driver:Y,slug:A.project.slug,environment:_,logger:f},{siteName:X,to:m?.to,dryRun:m?.dryRun,onlyIfLive:m?.onlyIfLive});for(let re of ne.perInstance||[])e(` ${X} ${re.instanceId}: ${re.output?.trim()||re.status}`);if(!ne.success)r(`Rollback of ${X} failed: ${ne.error||"unknown error"}`),process.exitCode=1}}catch(A){r(`Rollback failed: ${A.message}`),process.exitCode=1}}),D.command("deploy:history [site]","Show a compute site's deployment history").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Number of entries to show",{default:"20"}).action(async(t,m)=>{i("Deployment History");try{let A=await De(),_=m?.env||"production",z=t||Object.keys(A.sites||{})[0];if(!z){r("No site configured."),process.exitCode=1;return}let{getComputeDeployHistory:U}=await import("./chunk-67vf8myy.js"),Y=await U({driver:O({config:A}),slug:A.project.slug,environment:_,logger:f},{siteName:z,limit:Number.parseInt(m?.limit||"20",10)||20});if(!Y.success){r(`Could not read history: ${Y.error||"unknown error"}`),process.exitCode=1;return}for(let X of Y.perInstance||[])e(`
399
399
  ${X.instanceId}:`),e(X.output?.trimEnd()||"(no output)")}catch(A){r(`History lookup failed: ${A.message}`),process.exitCode=1}}),D.command("deploy:recipe <name> <script>","Run a reusable server recipe (a local bash file) across servers").option("--env <environment>","Environment (production, staging, development)").option("--user <user>","User to run the recipe as",{default:"root"}).action(async(t,m,A)=>{i(`Running Recipe: ${t}`);try{if(!bn(m)){r(`Recipe script not found: ${m}`),process.exitCode=1;return}let _=await De(),z=A?.env||"production",U=al(m,"utf8").split(`
400
- `),{runComputeRecipe:Y}=await import("./chunk-v2qk9jeb.js"),X=await Y({driver:O({config:_}),slug:_.project.slug,environment:z,logger:f},{name:t,script:U,user:A?.user});for(let ne of X.perInstance||[])e(`
401
- ${ne.instanceId}:`),e(ne.output?.trimEnd()||"(no output)");if(!X.success)process.exitCode=1}catch(_){r(`Recipe failed: ${_.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{restoreDatabaseBackup:z}=await import("./chunk-v2qk9jeb.js"),U=await z({driver:O({config:A}),slug:A.project.slug,environment:_,logger:f},{database:w(A),from:t});for(let Y of U.perInstance||[])e(` ${Y.instanceId}: ${Y.output?.trim()||Y.status}`);if(!U.success)r(`Restore failed: ${U.error||"unknown error"}`),process.exitCode=1}catch(A){r(`Restore failed: ${A.message}`),process.exitCode=1}}),D.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 De(),{buildQuickDeployCi:A,inferQuickDeployProvider:_}=await import("./chunk-vavwhhrp.js"),z=t?.provider?.toLowerCase();if(z&&!["github","gitlab","bitbucket"].includes(z))throw Error(`Unsupported CI provider '${t?.provider}'. Use github, gitlab, or bitbucket.`);let U=z;if(!U)try{let X=cl("git remote get-url origin",{stdio:["ignore","pipe","ignore"]}).toString().trim();U=_(X)}catch{}let Y=A(m,t?.env||"production",{provider:U,site:t?.site,skipDnsVerification:t?.skipDnsVerification,setup:bn("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(bn(Y.path)&&!t?.force){a(`${Y.path} already exists — re-run with --force to overwrite.`);return}iu(Kf(Y.path),{recursive:!0}),Hf(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}}),D.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 De(),A=t?.env||"production",{setMaintenance:_}=await import("./chunk-qsfhb3x7.js");await _(m,A,!0,t?.secret)}catch(m){r(`Failed to enable maintenance mode: ${m.message}`),process.exitCode=1}}),D.command("up","Bring the serverless app out of maintenance mode").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await De(),A=t?.env||"production",{setMaintenance:_}=await import("./chunk-qsfhb3x7.js");await _(m,A,!1)}catch(m){r(`Failed to disable maintenance mode: ${m.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{runAndRecordCommand:z}=await import("./chunk-qsfhb3x7.js"),{id:U,output:Y}=await z(A,_,t);if(e(Y),U>0)e(`
402
- (recorded as #${U} — re-run with \`cloud command:again ${U}\`)`)}catch(A){r(`Command failed: ${A.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",{listCommandHistory:_}=await import("./chunk-qsfhb3x7.js"),z=await _(m,A);if(!z.length){e("No command history yet.");return}let U=Number(t?.limit??20);i(`Command history — ${m.project.slug} (${A})`),c(["#","When","Status","Command"],z.slice(-U).reverse().map((Y)=>[String(Y.id),Y.timestamp,Y.status,Y.command]))}catch(m){r(`Failed to read history: ${m.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{getCommandRecord:z,runAndRecordCommand:U}=await import("./chunk-qsfhb3x7.js"),Y=await z(A,_,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 X=await U(A,_,Y.command);if(e(X.output),X.id>0)e(`
403
- (recorded as #${X.id})`)}catch(A){r(`Command failed: ${A.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{runDbQuery:z}=await import("./chunk-qsfhb3x7.js"),U=await z(A,_,t);e(U)}catch(A){r(`Query failed: ${A.message}`),process.exitCode=1}}),D.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,A)=>{i("Scaling serverless database");try{let _=await De(),z=A?.env||"production",U=Number(t),Y=Number(m);if(!(U>0)||!(Y>=U)){r("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:X}=await import("./chunk-qsfhb3x7.js");await X(_,z,U,Y)}catch(_){r(`Scale failed: ${_.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",_;if(t?.to){if(_=new Date(t.to),Number.isNaN(_.getTime())){r(`Invalid --to timestamp: ${t.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:z}=await import("./chunk-qsfhb3x7.js");await z(m,A,{toTime:_,latest:t?.latest,target:t?.target})}catch(m){r(`Restore failed: ${m.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",{serverlessInfo:_}=await import("./chunk-qsfhb3x7.js"),z=await _(m,A);if(i(`${z.slug} (${z.environment})`),e(`Stack: ${z.stackStatus}`),e(`Region: ${z.region}`),z.endpoint)e(`URL: ${z.endpoint}`);if(z.assetUrl)e(`Assets: ${z.assetUrl}`);if(e(`Scheduler:${z.scheduler==="off"?" off":` ${z.scheduler}`}`),e(`Queues: ${z.queues.length?z.queues.join(", "):"none"}`),e(`Warming: ${z.provisionedConcurrency>0?`provisioned concurrency ×${z.provisionedConcurrency}`:"none / ping-warm"}`),z.lastRelease)e(`Release: ${z.lastRelease.sha.slice(0,12)} @ ${z.lastRelease.timestamp}`);c(["Function","Version","Provisioned"],z.functions.map((U)=>[U.name,U.version,U.provisioned?`${U.provisioned.status} ${U.provisioned.allocated}/${U.provisioned.requested}`:"—"]))}catch(m){r(`Failed to read info: ${m.message}`),process.exitCode=1}}),D.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"),A=t?.ui||"ui";if(!m(`${A}/package.json`)){r(`No UI project at ${A}/ (expected ${A}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let _=await De(),z=t?.env||"production";d("Gathering live data from AWS");let U=null;if(_.environments?.[z]?.app){let{resolveDashboardData:re}=await import("./chunk-512ecg6y.js"),ie=await re(_,z).catch((ae)=>(a(`Serverless data unavailable (${ae.message}) — that view uses sample data.`),null));if(ie)U={...U??{},...ie}}if(_.infrastructure?.compute){let{resolveServerDashboardData:re}=await import("./chunk-7ewbxsan.js"),ie=await re(_,z).catch(()=>null);if(ie){if(ie._serverReachable===!1)a("Server box not reachable over SSM — server view uses config + sample data.");U={...U??{},...ie}}}d("Building dashboard");let{encodeDashboardPayload:Y}=await import("./chunk-d2fq60kd.js"),{execSync:X}=await import("node:child_process"),{rmSync:ne}=await import("node:fs");for(let re of[".stx/ssg-cache",".stx/cache"])ne(`${A}/${re}`,{recursive:!0,force:!0});X("bun run build",{cwd:A,stdio:"inherit",env:{...process.env,...U?{TSCLOUD_DASHBOARD_DATA:Y(U)}:{}}}),n(`Dashboard built → ${A}/dist${U?" (live data)":" (sample data)"}`)}catch(m){r(`Dashboard build failed: ${m.message}`),process.exitCode=1}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.php||"8.3",U=`${t?.name||"tscloud-php"}-${z.replace(".","")}-${_}`,Y=t?.bucket||`${m?.project.slug||"tscloud"}-layers`,{buildPhpRuntimeLayerZip:X}=await import("./chunk-e6ewfmbp.js"),{S3Client:ne}=await import("./chunk-f9469h6q.js"),{LambdaClient:re}=await import("./chunk-azarn24c.js"),ie=X({architecture:_,phpVersion:z,onStep:($e)=>d($e)});e(`Layer: ${ie.fileCount} files, ${(ie.zip.length/1024/1024).toFixed(1)} MB`);let ae=new ne(A);if(!await ae.bucketExists(Y))d(`Creating layer bucket ${Y}`),await ae.createBucket(Y);let be=`layers/${U}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:Y,key:be,body:ie.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new re(A).publishLayerVersion({LayerName:U,Description:`ts-cloud PHP ${z} runtime (${_})`,Content:{S3Bucket:Y,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});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}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.node||"24",{buildNodeRuntimeLayerZip:U}=await import("./chunk-e6ewfmbp.js"),{S3Client:Y}=await import("./chunk-f9469h6q.js"),{LambdaClient:X}=await import("./chunk-azarn24c.js"),ne=U({architecture:_,version:z,onStep:($e)=>d($e)}),re=`${t?.name||"tscloud-node"}-${ne.version.split(".")[0]}-${_}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Node ${ne.version}, ${(ne.zip.length/1024/1024).toFixed(1)} MB`);let ae=new Y(A);if(!await ae.bucketExists(ie))d(`Creating layer bucket ${ie}`),await ae.createBucket(ie);let be=`layers/${re}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:ie,key:be,body:ne.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new X(A).publishLayerVersion({LayerName:re,Description:`ts-cloud Node ${ne.version} runtime (${_})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});Ee(["Node runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'node', runtimeVersion: '${ne.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}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.bun||"latest",{buildBunRuntimeLayerZip:U}=await import("./chunk-e6ewfmbp.js"),{S3Client:Y}=await import("./chunk-f9469h6q.js"),{LambdaClient:X}=await import("./chunk-azarn24c.js"),ne=U({architecture:_,version:z,onStep:($e)=>d($e)}),re=`${t?.name||"tscloud-bun"}-${ne.version.replace(/\./g,"")}-${_}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Bun ${ne.version}, ${(ne.zip.length/1024/1024).toFixed(1)} MB`);let ae=new Y(A);if(!await ae.bucketExists(ie))d(`Creating layer bucket ${ie}`),await ae.createBucket(ie);let be=`layers/${re}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:ie,key:be,body:ne.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new X(A).publishLayerVersion({LayerName:re,Description:`ts-cloud Bun ${ne.version} runtime (${_})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});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-67vf8myy.js"),X=await Y({driver:O({config:_}),slug:_.project.slug,environment:z,logger:f},{name:t,script:U,user:A?.user});for(let ne of X.perInstance||[])e(`
401
+ ${ne.instanceId}:`),e(ne.output?.trimEnd()||"(no output)");if(!X.success)process.exitCode=1}catch(_){r(`Recipe failed: ${_.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{restoreDatabaseBackup:z}=await import("./chunk-67vf8myy.js"),U=await z({driver:O({config:A}),slug:A.project.slug,environment:_,logger:f},{database:w(A),from:t});for(let Y of U.perInstance||[])e(` ${Y.instanceId}: ${Y.output?.trim()||Y.status}`);if(!U.success)r(`Restore failed: ${U.error||"unknown error"}`),process.exitCode=1}catch(A){r(`Restore failed: ${A.message}`),process.exitCode=1}}),D.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 De(),{buildQuickDeployCi:A,inferQuickDeployProvider:_}=await import("./chunk-fhe0mdjg.js"),z=t?.provider?.toLowerCase();if(z&&!["github","gitlab","bitbucket"].includes(z))throw Error(`Unsupported CI provider '${t?.provider}'. Use github, gitlab, or bitbucket.`);let U=z;if(!U)try{let X=cl("git remote get-url origin",{stdio:["ignore","pipe","ignore"]}).toString().trim();U=_(X)}catch{}let Y=A(m,t?.env||"production",{provider:U,site:t?.site,skipDnsVerification:t?.skipDnsVerification,setup:bn("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(bn(Y.path)&&!t?.force){a(`${Y.path} already exists — re-run with --force to overwrite.`);return}iu(Kf(Y.path),{recursive:!0}),Hf(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}}),D.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 De(),A=t?.env||"production",{setMaintenance:_}=await import("./chunk-9qdrv6zp.js");await _(m,A,!0,t?.secret)}catch(m){r(`Failed to enable maintenance mode: ${m.message}`),process.exitCode=1}}),D.command("up","Bring the serverless app out of maintenance mode").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await De(),A=t?.env||"production",{setMaintenance:_}=await import("./chunk-9qdrv6zp.js");await _(m,A,!1)}catch(m){r(`Failed to disable maintenance mode: ${m.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{runAndRecordCommand:z}=await import("./chunk-9qdrv6zp.js"),{id:U,output:Y}=await z(A,_,t);if(e(Y),U>0)e(`
402
+ (recorded as #${U} — re-run with \`cloud command:again ${U}\`)`)}catch(A){r(`Command failed: ${A.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",{listCommandHistory:_}=await import("./chunk-9qdrv6zp.js"),z=await _(m,A);if(!z.length){e("No command history yet.");return}let U=Number(t?.limit??20);i(`Command history — ${m.project.slug} (${A})`),c(["#","When","Status","Command"],z.slice(-U).reverse().map((Y)=>[String(Y.id),Y.timestamp,Y.status,Y.command]))}catch(m){r(`Failed to read history: ${m.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{getCommandRecord:z,runAndRecordCommand:U}=await import("./chunk-9qdrv6zp.js"),Y=await z(A,_,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 X=await U(A,_,Y.command);if(e(X.output),X.id>0)e(`
403
+ (recorded as #${X.id})`)}catch(A){r(`Command failed: ${A.message}`),process.exitCode=1}}),D.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 A=await De(),_=m?.env||"production",{runDbQuery:z}=await import("./chunk-9qdrv6zp.js"),U=await z(A,_,t);e(U)}catch(A){r(`Query failed: ${A.message}`),process.exitCode=1}}),D.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,A)=>{i("Scaling serverless database");try{let _=await De(),z=A?.env||"production",U=Number(t),Y=Number(m);if(!(U>0)||!(Y>=U)){r("Provide valid capacities: min > 0 and max >= min (e.g. `serverless:db-scale 0.5 8`)."),process.exitCode=1;return}let{scaleServerlessDatabase:X}=await import("./chunk-9qdrv6zp.js");await X(_,z,U,Y)}catch(_){r(`Scale failed: ${_.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",_;if(t?.to){if(_=new Date(t.to),Number.isNaN(_.getTime())){r(`Invalid --to timestamp: ${t.to} (use ISO-8601, e.g. 2026-06-18T10:00:00Z).`),process.exitCode=1;return}}let{restoreServerlessDatabase:z}=await import("./chunk-9qdrv6zp.js");await z(m,A,{toTime:_,latest:t?.latest,target:t?.target})}catch(m){r(`Restore failed: ${m.message}`),process.exitCode=1}}),D.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 De(),A=t?.env||"production",{serverlessInfo:_}=await import("./chunk-9qdrv6zp.js"),z=await _(m,A);if(i(`${z.slug} (${z.environment})`),e(`Stack: ${z.stackStatus}`),e(`Region: ${z.region}`),z.endpoint)e(`URL: ${z.endpoint}`);if(z.assetUrl)e(`Assets: ${z.assetUrl}`);if(e(`Scheduler:${z.scheduler==="off"?" off":` ${z.scheduler}`}`),e(`Queues: ${z.queues.length?z.queues.join(", "):"none"}`),e(`Warming: ${z.provisionedConcurrency>0?`provisioned concurrency ×${z.provisionedConcurrency}`:"none / ping-warm"}`),z.lastRelease)e(`Release: ${z.lastRelease.sha.slice(0,12)} @ ${z.lastRelease.timestamp}`);c(["Function","Version","Provisioned"],z.functions.map((U)=>[U.name,U.version,U.provisioned?`${U.provisioned.status} ${U.provisioned.allocated}/${U.provisioned.requested}`:"—"]))}catch(m){r(`Failed to read info: ${m.message}`),process.exitCode=1}}),D.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"),A=t?.ui||"ui";if(!m(`${A}/package.json`)){r(`No UI project at ${A}/ (expected ${A}/package.json). Pass --ui <dir>.`),process.exitCode=1;return}let _=await De(),z=t?.env||"production";d("Gathering live data from AWS");let U=null;if(_.environments?.[z]?.app){let{resolveDashboardData:re}=await import("./chunk-g6ph425d.js"),ie=await re(_,z).catch((ae)=>(a(`Serverless data unavailable (${ae.message}) — that view uses sample data.`),null));if(ie)U={...U??{},...ie}}if(_.infrastructure?.compute){let{resolveServerDashboardData:re}=await import("./chunk-m5jvp6ph.js"),ie=await re(_,z).catch(()=>null);if(ie){if(ie._serverReachable===!1)a("Server box not reachable over SSM — server view uses config + sample data.");U={...U??{},...ie}}}d("Building dashboard");let{encodeDashboardPayload:Y}=await import("./chunk-d2fq60kd.js"),{execSync:X}=await import("node:child_process"),{rmSync:ne}=await import("node:fs");for(let re of[".stx/ssg-cache",".stx/cache"])ne(`${A}/${re}`,{recursive:!0,force:!0});X("bun run build",{cwd:A,stdio:"inherit",env:{...process.env,...U?{TSCLOUD_DASHBOARD_DATA:Y(U)}:{}}}),n(`Dashboard built → ${A}/dist${U?" (live data)":" (sample data)"}`)}catch(m){r(`Dashboard build failed: ${m.message}`),process.exitCode=1}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.php||"8.3",U=`${t?.name||"tscloud-php"}-${z.replace(".","")}-${_}`,Y=t?.bucket||`${m?.project.slug||"tscloud"}-layers`,{buildPhpRuntimeLayerZip:X}=await import("./chunk-83brtkvn.js"),{S3Client:ne}=await import("./chunk-f9469h6q.js"),{LambdaClient:re}=await import("./chunk-azarn24c.js"),ie=X({architecture:_,phpVersion:z,onStep:($e)=>d($e)});e(`Layer: ${ie.fileCount} files, ${(ie.zip.length/1024/1024).toFixed(1)} MB`);let ae=new ne(A);if(!await ae.bucketExists(Y))d(`Creating layer bucket ${Y}`),await ae.createBucket(Y);let be=`layers/${U}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:Y,key:be,body:ie.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new re(A).publishLayerVersion({LayerName:U,Description:`ts-cloud PHP ${z} runtime (${_})`,Content:{S3Bucket:Y,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});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}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.node||"24",{buildNodeRuntimeLayerZip:U}=await import("./chunk-83brtkvn.js"),{S3Client:Y}=await import("./chunk-f9469h6q.js"),{LambdaClient:X}=await import("./chunk-azarn24c.js"),ne=U({architecture:_,version:z,onStep:($e)=>d($e)}),re=`${t?.name||"tscloud-node"}-${ne.version.split(".")[0]}-${_}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Node ${ne.version}, ${(ne.zip.length/1024/1024).toFixed(1)} MB`);let ae=new Y(A);if(!await ae.bucketExists(ie))d(`Creating layer bucket ${ie}`),await ae.createBucket(ie);let be=`layers/${re}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:ie,key:be,body:ne.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new X(A).publishLayerVersion({LayerName:re,Description:`ts-cloud Node ${ne.version} runtime (${_})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});Ee(["Node runtime layer published","",`ARN: ${le.LayerVersionArn}`,"","Reference it in your config:",` app: { kind: 'node', runtimeVersion: '${ne.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}}),D.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 De().catch(()=>null),A=t?.region||m?.project.region||"us-east-1",_=t?.arch||"x86_64",z=t?.bun||"latest",{buildBunRuntimeLayerZip:U}=await import("./chunk-83brtkvn.js"),{S3Client:Y}=await import("./chunk-f9469h6q.js"),{LambdaClient:X}=await import("./chunk-azarn24c.js"),ne=U({architecture:_,version:z,onStep:($e)=>d($e)}),re=`${t?.name||"tscloud-bun"}-${ne.version.replace(/\./g,"")}-${_}`,ie=t?.bucket||`${m?.project.slug||"tscloud"}-layers`;e(`Layer: Bun ${ne.version}, ${(ne.zip.length/1024/1024).toFixed(1)} MB`);let ae=new Y(A);if(!await ae.bucketExists(ie))d(`Creating layer bucket ${ie}`),await ae.createBucket(ie);let be=`layers/${re}.zip`;d("Uploading layer zip"),await ae.putObject({bucket:ie,key:be,body:ne.zip,contentType:"application/zip"}),d("Publishing layer version");let le=await new X(A).publishLayerVersion({LayerName:re,Description:`ts-cloud Bun ${ne.version} runtime (${_})`,Content:{S3Bucket:ie,S3Key:be},CompatibleRuntimes:["provided.al2023"],CompatibleArchitectures:[_]});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}}),D.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 De(),A=t?.env||"production",_=t?.stack||T(m,A),z=m.project.region||"us-east-1";e(`Stack: ${_}`),e(`Region: ${z}`);let U=new s("Checking deployment status...");U.start();let X=await new v(z).describeStacks({stackName:_});if(X.Stacks.length===0){U.fail("Stack not found"),Pr("No deployment found for this environment");return}let ne=X.Stacks[0];if(U.succeed("Status retrieved"),e(`
407
407
  Status: ${ne.StackStatus}`),e(`Created: ${ne.CreationTime}`),ne.LastUpdatedTime)e(`Last Updated: ${ne.LastUpdatedTime}`);if(ne.Outputs&&ne.Outputs.length>0){e(`
408
408
  Outputs:`);for(let re of ne.Outputs)e(` ${re.OutputKey}: ${re.OutputValue}`)}}catch(m){r(`Failed to get status: ${m.message}`)}}),D.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 De(),A=t?.env||"production",_=t?.stack||T(m,A),z=m.project.region||"us-east-1";if(e(`Stack: ${_}`),e(`Region: ${z}`),!await u(`