@stacksjs/ts-cloud 0.7.73 → 0.7.75

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 (56) hide show
  1. package/dist/bin/cli.js +4 -4
  2. package/dist/{chunk-1p8jah5z.js → chunk-wwv7rmmh.js} +1 -1
  3. package/dist/{chunk-j6msc2m2.js → chunk-x6rzz0bt.js} +4 -2
  4. package/dist/deploy/index.js +2 -2
  5. package/dist/drivers/index.js +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/ui/access-denied.html +2 -2
  8. package/dist/ui/account/automation.html +3 -3
  9. package/dist/ui/account/security.html +2 -2
  10. package/dist/ui/applications/compose.html +4 -4
  11. package/dist/ui/applications/new.html +2 -2
  12. package/dist/ui/data/backups.html +4 -4
  13. package/dist/ui/data/services.html +4 -4
  14. package/dist/ui/data/volumes.html +4 -4
  15. package/dist/ui/index.html +4 -4
  16. package/dist/ui/integrations.html +2 -2
  17. package/dist/ui/operations/alerts.html +4 -4
  18. package/dist/ui/operations/configuration.html +4 -4
  19. package/dist/ui/operations/jobs.html +4 -4
  20. package/dist/ui/operations/maintenance.html +4 -4
  21. package/dist/ui/operations/observability.html +4 -4
  22. package/dist/ui/operations/previews.html +4 -4
  23. package/dist/ui/operations/queue.html +4 -4
  24. package/dist/ui/operations/regions.html +4 -4
  25. package/dist/ui/operations/releases.html +3 -3
  26. package/dist/ui/operations/workloads.html +4 -4
  27. package/dist/ui/security.html +2 -2
  28. package/dist/ui/server/actions.html +3 -3
  29. package/dist/ui/server/activity.html +2 -2
  30. package/dist/ui/server/capacity.html +4 -4
  31. package/dist/ui/server/database.html +4 -4
  32. package/dist/ui/server/deployments.html +4 -4
  33. package/dist/ui/server/diagnostics.html +2 -2
  34. package/dist/ui/server/firewall.html +4 -4
  35. package/dist/ui/server/fleet.html +4 -4
  36. package/dist/ui/server/logs.html +4 -4
  37. package/dist/ui/server/metrics.html +4 -4
  38. package/dist/ui/server/security.html +2 -2
  39. package/dist/ui/server/services.html +2 -2
  40. package/dist/ui/server/sites.html +4 -4
  41. package/dist/ui/server/ssh-keys.html +3 -3
  42. package/dist/ui/server/team.html +4 -4
  43. package/dist/ui/server/terminal.html +2 -2
  44. package/dist/ui/serverless/alarms.html +4 -4
  45. package/dist/ui/serverless/assets.html +2 -2
  46. package/dist/ui/serverless/cost.html +2 -2
  47. package/dist/ui/serverless/data.html +4 -4
  48. package/dist/ui/serverless/firewall.html +2 -2
  49. package/dist/ui/serverless/functions.html +3 -3
  50. package/dist/ui/serverless/logs.html +4 -4
  51. package/dist/ui/serverless/metrics.html +2 -2
  52. package/dist/ui/serverless/queues.html +4 -4
  53. package/dist/ui/serverless/secrets.html +3 -3
  54. package/dist/ui/serverless/traces.html +4 -4
  55. package/dist/ui/serverless.html +4 -4
  56. package/package.json +3 -3
package/dist/bin/cli.js CHANGED
@@ -8386,7 +8386,7 @@ async function sendFallbackSms(to, message) {
8386
8386
  input, output, error, attempt, priority, lease_owner, lease_expires_at, cancel_requested_at, started_at, finished_at, version, created_at, updated_at)
8387
8387
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[d.id,d.projectId??null,d.environmentId??null,d.resourceId??null,d.actorId??null,d.kind,d.state,d.correlationId,d.idempotencyKey??null,FT(d.input),FT(d.output),xw(d.error)??null,d.attempt,d.priority,d.leaseOwner??null,d.leaseExpiresAt??null,d.cancelRequestedAt??null,d.startedAt??null,d.finishedAt??null,d.version,d.createdAt,d.updatedAt]);for(let d of E.events)fE(this.database,`INSERT INTO events (sequence, id, organization_id, project_id, operation_id, resource_id, actor_id, correlation_id, type, level, payload, created_at)
8388
8388
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[d.sequence,d.id,d.organizationId??null,d.projectId??null,d.operationId??null,d.resourceId??null,d.actorId??null,d.correlationId,d.type,d.level,FT(d.payload),d.createdAt]);for(let[d,R]of Object.entries(E.settings))fE(this.database,"INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)",[d,FT(R),this.now()]);for(let d of E.tags??[])fE(this.database,"INSERT INTO tags (id, project_id, name, normalized_name, color, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[d.id,d.projectId,d.name,d.normalizedName,d.color,d.createdAt,d.updatedAt]);for(let d of E.resourceTags??[])fE(this.database,"INSERT INTO resource_tags (resource_id, tag_id, created_at) VALUES (?, ?, ?)",[d.resourceId,d.tagId,d.createdAt]);for(let d of E.savedFilters??[])fE(this.database,"INSERT INTO saved_filters (id, actor_key, name, route_id, query, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[d.id,d.actorKey,d.name,d.routeId,FT(d.query),d.createdAt,d.updatedAt]);for(let d of E.navigationItems??[])fE(this.database,"INSERT INTO navigation_items (actor_key, entity_type, entity_id, favorite, last_visited_at, visit_count) VALUES (?, ?, ?, ?, ?, ?)",[d.actorKey,d.entityType,d.entityId,d.favorite?1:0,d.lastVisitedAt,d.visitCount])})}}var tH=65536,bw=16384,mZ,aZ,sZ,OH;var UH=cE(async()=>{Pw();Vw();qw();await mE();mZ=["succeeded","failed","cancelled","timed_out"],aZ={queued:["running","cancelled","timed_out"],running:["queued","succeeded","failed","cancelled","timed_out"],succeeded:[],failed:["queued"],cancelled:["queued"],timed_out:["queued"]},sZ=/(?:^|_)(?:authorization|cookie|credential|password|passwd|secret|token|api_?key|private_?key|access_?key)(?:$|_)/i,OH=/(?:authorization|password|secret|token|api[_-]?key|private[_-]?key|access[_-]?key)\s*[=:]\s*[^\s,;]+/gi});function $H(E,T){if(!E||typeof E!=="object"||Array.isArray(E))return[];let _=[];for(let[d,R]of Object.entries(E)){if(!T.has(d.toLowerCase()))continue;if(typeof R==="string")_.push(R);else if(Array.isArray(R))_.push(...R.filter((h)=>typeof h==="string"))}return _}function vw(E){return E.toLowerCase().trim().replace(/[^a-z0-9._:/@-]+/g," ")}function nw(E,T,_){let d=vw(E),R=vw(T),h=vw(_);if(!d)return 0;if(R===d)return 1000;if(R.startsWith(d))return 800-Math.min(100,R.length-d.length);if(R.includes(d))return 650-Math.min(100,R.indexOf(d));let r=d.split(/\s+/).filter(Boolean);if(r.every((A)=>h.includes(A)))return 400+r.length*10;let N=0;for(let A of d){if(N=h.indexOf(A,N),N<0)return 0;N++}return Math.max(1,180-Math.floor(h.length/20))}function Tq(E,T){let _=E.kind.toLowerCase();if(_==="server"||_==="compute")return{type:"server",href:`/server/metrics?env=${encodeURIComponent(T)}`};if(_.includes("database")||["mysql","postgres","postgresql","sqlite","redis"].includes(_))return{type:"database",href:`/server/database?env=${encodeURIComponent(T)}&database=${encodeURIComponent(E.slug)}`};return{type:"service",href:`/server/sites?env=${encodeURIComponent(T)}&service=${encodeURIComponent(E.slug)}`}}function lw(E,T){let _=E.getProject(T.projectId);if(!_)return[];let d=E.listEnvironments(_.id),R=new Map(d.map((t)=>[t.id,t])),h=E.listResourceTags(_.id),r=new Map;for(let t of h){let O=r.get(t.resourceId)??[];O.push({id:t.tag.id,name:t.tag.name,color:t.tag.color}),r.set(t.resourceId,O)}let N=[],A=T.allowedResourceSlugs!==void 0;if(!A){N.push({type:"project",id:_.id,title:_.name,subtitle:_.slug,href:`/?project=${encodeURIComponent(_.slug)}`,tags:[],score:0});for(let t of d)N.push({type:"environment",id:t.id,title:t.name,subtitle:`${_.name} · ${t.kind}`,href:`/?env=${encodeURIComponent(t.slug)}`,environment:t.slug,tags:[],score:0})}let S=E.listResources(_.id).filter((t)=>!T.allowedResourceSlugs||T.allowedResourceSlugs.has(t.slug));for(let t of S){let O=t.environmentId?R.get(t.environmentId):void 0,U=r.get(t.id)??[],D=$H(t.desiredState,oZ),C=[t.name,t.slug,t.kind,t.provider,t.providerId,O?.slug,...D,...U.map((c)=>c.name)].filter(Boolean).join(" "),w=Tq(t,O?.slug??d[0]?.slug??"");N.push({type:w.type,id:t.id,title:t.name,subtitle:[t.kind,...D.slice(0,2)].join(" · "),href:w.href,environment:O?.slug,provider:t.provider,tags:U,score:nw(T.query,t.name,C)})}if(!A)for(let t of E.listOperations({projectId:_.id,limit:500})){let O=t.environmentId?R.get(t.environmentId):void 0,U=$H(t.input,Eq),D=t.kind.includes("deploy"),C=U[0]??t.kind,w=[t.kind,t.id,t.correlationId,t.state,...U].join(" ");N.push({type:D?"deployment":"operation",id:t.id,title:C,subtitle:`${t.kind} · ${t.state}`,href:`/server/activity?env=${encodeURIComponent(O?.slug??d[0]?.slug??"")}&operation=${encodeURIComponent(t.id)}`,environment:O?.slug,status:t.state,tags:[],score:nw(T.query,C,w)})}for(let t of N)if(t.score===0)t.score=nw(T.query,t.title,`${t.title} ${t.subtitle} ${t.environment??""} ${t.provider??""}`);let L={service:0,server:1,database:2,deployment:3,environment:4,project:5,operation:6};return N.filter((t)=>t.score>0).sort((t,O)=>O.score-t.score||L[t.type]-L[O.type]||t.title.localeCompare(O.title)||t.id.localeCompare(O.id)).slice(0,Math.min(50,Math.max(1,T.limit??20)))}var oZ,Eq;var DH=cE(()=>{oZ=new Set(["domain","domains","hostname","hostnames","url","repository","repo","image","label","labels"]),Eq=new Set(["sha","commit","commitsha","release","releaseid"])});var d_=cE(async()=>{Vw();DH();Pw();await UH();qw()});import{createHmac as _q}from"node:crypto";function hd(E){return[...new Set(E)].sort()}function IH(E,T={}){let _=E.kind==="secret";return{id:E.id,key:E.key,kind:E.kind,scope:E.scope,inherited:!!T.inherited,overridden:!!T.overridden,required:E.required,backend:!_||T.canReadSecretMetadata?E.backend:void 0,backendVersion:!_||T.canReadSecretMetadata?E.backendVersion:void 0,reference:_&&T.canReadSecretMetadata?E.secretRef:void 0,value:!_?E.value:void 0,lastUsedAt:E.lastUsedAt,rotatedAt:E.rotatedAt,version:E.version,updatedAt:E.updatedAt}}class vA{store;backends=new Map;fingerprintKey;now;constructor(E,T){if(this.store=E,this.fingerprintKey=T.fingerprintKey??T.encryptionKey,this.now=T.now??(()=>new Date),!this.fingerprintKey)throw Error("Configuration fingerprint key is required.");let _=T.backends??[new zr(E.controlPlane,T.encryptionKey,this.now)];for(let d of _)this.backends.set(d.kind,d)}list(E){let T=E.search?.toLowerCase();return this.store.list(E).filter((_)=>!T||_.key.toLowerCase().includes(T)).map((_)=>IH(_,{canReadSecretMetadata:E.canReadSecretMetadata}))}plan(E){let T=this.store.list({projectId:E.projectId,scope:E.scope}),_=new Map(T.map((A)=>[A.key,A])),d=[],R=[],h=[],r=[];for(let[A,S]of Object.entries(E.values)){d.push(...this.warnings(A,S));let L=_.get(A);if(!L)R.push(A);else if(L.valueFingerprint!==this.fingerprint(S))h.push(A);else r.push(A)}let N=E.removeMissing?T.filter((A)=>!Object.hasOwn(E.values,A.key)).map((A)=>A.key):[];return{added:hd(R),changed:hd(h),removed:hd(N),unchanged:hd(r),affectedResourceIds:this.affectedResources(E.projectId,E.scope,[...R,...h,...N]),warnings:d}}async set(E){let T=this.requestHash(E),_=E.idempotencyKey;if(_){let D=this.store.mutation(_);if(D){if(D.requestHash!==T)throw Error("Idempotency key was already used for a different configuration mutation.");let C=this.store.get(String(D.result.entryId??""));if(!C)throw Error("Idempotent configuration result is no longer available.");return{entry:C,mutation:D.result.mutation,warnings:[]}}}if(E.value!=null&&dq.test(E.value))throw Error("Secret references must use the reference field, not a plaintext value field.");let d=this.store.find(E.projectId,E.scope,E.key),R=this.fingerprint(E.value??E.reference??"");if(d&&E.expectedVersion!=null&&d.version!==E.expectedVersion)throw Error("Configuration entry changed; refresh and retry.");if(d&&d.kind!==E.kind)throw Error("Delete the existing entry before changing between variable and secret kinds.");let h=E.kind==="variable"?"plaintext":E.backend??(E.reference?"external":"local_encrypted");if(!!d&&(d.valueFingerprint!==R||d.backend!==h||d.required!==!!E.required)&&(this.isProduction(d)||this.store.dependencies(d.id).length>0)&&!E.confirmed)throw Error("Confirmation is required because this replacement affects production or dependent services.");let N=E.reference,A;if(E.kind==="secret"){let D=this.backend(h);if(E.reference&&E.value==null){if(!await D.validate(E.reference))throw Error("Secret backend reference is unavailable or invalid.");A=d?.backendVersion??"external"}else{if(E.value==null)throw Error("A secret value or external reference is required.");let C=await D.put({reference:d?.backend===h?d.secretRef:void 0,name:this.backendName(E),value:E.value,idempotencyKey:_??crypto.randomUUID()});N=C.reference,A=C.version}}let S=E.kind==="variable"?E.value:void 0;if(E.kind==="variable"&&S==null)throw Error("A variable value is required.");let L=!d||d.valueFingerprint!==R||d.backend!==h||d.secretRef!==N||d.backendVersion!==A||d.required!==!!E.required,t=d?L?this.store.update(d.id,d.version,{value:S,valueFingerprint:R,secretRef:N,backend:h,backendVersion:A,required:!!E.required,metadata:xE(E.metadata??d.metadata),rotatedAt:E.kind==="secret"?this.now().toISOString():d.rotatedAt}):d:this.store.create({organizationId:E.organizationId,projectId:E.projectId,scope:E.scope,key:E.key,kind:E.kind,value:S,valueFingerprint:R,secretRef:N,backend:h,backendVersion:A,origin:E.origin??"managed",required:!!E.required,metadata:xE(E.metadata??{}),rotatedAt:E.kind==="secret"?this.now().toISOString():void 0}),O=this.affectedResources(E.projectId,E.scope,[E.key]),U={added:d?[]:[E.key],changed:d&&L?[E.key]:[],removed:[],unchanged:d&&!L?[E.key]:[],affectedResourceIds:O,versions:{[E.key]:t.version}};if(_)this.store.recordMutation({projectId:E.projectId,idempotencyKey:_,requestHash:T,actorId:E.actorId,result:{entryId:t.id,mutation:U}});return this.audit(E.projectId,E.actorId,d&&L?"configuration.updated":d?"configuration.unchanged":"configuration.created",t,O),{entry:t,mutation:U,warnings:this.warnings(E.key,E.value??"")}}async importDotenv(E){let T=Yw(E.source);if(!T.valid)return{document:T,warnings:[]};let _=new Set(E.secretKeys??[]),d={added:[],changed:[],removed:[],unchanged:[],affectedResourceIds:[],versions:{}},R=[];for(let[h,r]of Object.entries(T.values)){let N=await this.set({...E,source:void 0,key:h,value:r,kind:_.has(h)?"secret":"variable",idempotencyKey:E.idempotencyKey?`${E.idempotencyKey}:${h}`:void 0});d.added.push(...N.mutation.added),d.changed.push(...N.mutation.changed),d.unchanged.push(...N.mutation.unchanged),d.affectedResourceIds.push(...N.mutation.affectedResourceIds),Object.assign(d.versions,N.mutation.versions),R.push(...N.warnings)}return d.added=hd(d.added),d.changed=hd(d.changed),d.unchanged=hd(d.unchanged),d.affectedResourceIds=hd(d.affectedResourceIds),{document:T,mutation:d,warnings:R}}exportVariables(E){return ew(Object.fromEntries(this.store.list({projectId:E.projectId,scope:E.scope,kind:"variable"}).map((T)=>[T.key,T.value??""])))}async transfer(E){let T=this.store.get(E.entryId);if(!T)throw Error("Configuration entry was not found.");if(T.scope.type===E.targetScope.type&&T.scope.id===E.targetScope.id)throw Error("Choose a different destination scope.");let _=T.kind==="variable"?T.value:T.backend==="external"?void 0:await this.backend(T.backend).resolve(T.secretRef),d=T.kind==="secret"?T.backend:void 0,R=await this.set({organizationId:T.organizationId,projectId:T.projectId,scope:E.targetScope,key:T.key,kind:T.kind,value:_,reference:T.backend==="external"?T.secretRef:void 0,backend:d,required:T.required,metadata:T.metadata,confirmed:E.confirmed,actorId:E.actorId,idempotencyKey:E.idempotencyKey?`${E.idempotencyKey}:copy`:void 0,origin:T.origin});if(E.mode==="move")await this.remove({entryId:T.id,expectedVersion:T.version,confirmed:E.confirmed,actorId:E.actorId});let h={added:R.mutation.added,changed:R.mutation.changed,removed:E.mode==="move"?[T.key]:[],unchanged:R.mutation.unchanged,affectedResourceIds:hd([...R.mutation.affectedResourceIds,...this.affectedResources(T.projectId,T.scope,[T.key])]),versions:R.mutation.versions};return{entry:R.entry,mutation:h}}async resolve(E){let T=this.store.list({projectId:E.projectId}),_=T.filter((S)=>this.applies(S,E)).sort((S,L)=>this.rank(S.scope.type)-this.rank(L.scope.type)),d=new Map,R=new Set;for(let S of _){if(d.has(S.key))R.add(S.key);d.set(S.key,S)}let h={},r={},N=[],A=new Set(E.allowedPreviewSecrets??[]);for(let[S,L]of d){if(E.previewId&&L.kind==="secret"&&L.scope.type!=="preview"&&(!E.trustedPreview||!A.has(S)))continue;if(L.kind==="variable")h[S]=L.value??"";else if(E.nativeReferences)h[S]=L.secretRef;else{let t=this.backend(L.backend);if(!await t.validate(L.secretRef)){if(N.push({key:S,code:"stale_reference",message:`${S} points to an unavailable secret.`}),L.required)N.push({key:S,code:"missing_required",message:`${S} is required but unavailable.`});continue}h[S]=await t.resolve(L.secretRef)}r[S]=IH(L,{inherited:L.scope.type!==(E.previewId?"preview":E.functionId?"function":E.resourceId?"service":E.environmentId?"environment":"project"),overridden:R.has(S),canReadSecretMetadata:E.canReadSecretMetadata}),this.store.controlPlane.database.run("UPDATE configuration_entries SET last_used_at=? WHERE id=?",[this.now().toISOString(),L.id])}return{values:h,entries:r,warnings:N,configurationHash:this.fingerprint([...d.values()].map((S)=>`${S.key}:${S.valueFingerprint}:${S.version}`).sort().join(`
8389
- `))}}async reveal(E){let T=this.store.get(E.entryId);if(!T||T.kind!=="secret")throw Error("Configuration secret was not found.");if(!E.canRevealSecrets)throw Error("Secret reveal permission is required.");if(!E.recentlyAuthenticated)throw Error("Recent authentication is required to reveal a secret.");let _=await this.backend(T.backend).resolve(T.secretRef);return this.audit(T.projectId,E.actorId,"configuration.secret.revealed",T,[]),_}async remove(E){let T=this.store.get(E.entryId);if(!T)throw Error("Configuration entry was not found.");let _=this.store.dependencies(T.id);if(((T.scope.environmentId?this.store.controlPlane.listEnvironments(T.projectId).some((r)=>r.id===T.scope.environmentId&&r.kind==="production"):T.scope.type==="project")||_.length)&&!E.confirmed)throw Error("Confirmation is required because this configuration affects production or dependent services.");if(T.kind==="secret"&&T.backend!=="external")await this.backend(T.backend).remove(T.secretRef);this.store.remove(T.id,E.expectedVersion);let R=hd(_.map((r)=>r.resourceId)),h={added:[],changed:[],removed:[T.key],unchanged:[],affectedResourceIds:R,versions:{}};return this.audit(T.projectId,E.actorId,"configuration.deleted",T,R),h}applies(E,T){if(E.scope.type==="project")return!0;if(E.scope.type==="environment")return E.scope.id===T.environmentId;if(E.scope.type==="service")return E.scope.id===T.resourceId;if(E.scope.type==="function")return E.scope.id===T.functionId;return E.scope.id===T.previewId}rank(E){return{project:0,environment:1,service:2,function:3,preview:4}[E]}fingerprint(E){return`hmac-sha256:${_q("sha256",this.fingerprintKey).update(E).digest("hex")}`}requestHash(E){return this.fingerprint(JSON.stringify({...E,idempotencyKey:void 0,actorId:void 0}))}backend(E){let T=this.backends.get(E);if(!T)throw Error(`Configuration secret backend is not configured: ${E}`);return T}backendName(E){return`ts-cloud/${E.projectId}/${E.scope.type}/${E.scope.id}/${E.key}`.replace(/[^A-Za-z0-9/_+=.@-]/g,"-")}isProduction(E){return E.scope.type==="project"||!!E.scope.environmentId&&this.store.controlPlane.listEnvironments(E.projectId).some((T)=>T.id===E.scope.environmentId&&T.kind==="production")}warnings(E,T){let _=[];if(Rq.test(E))_.push({key:E,code:"reserved",message:`${E} may be reserved by the runtime or provider.`});if(Buffer.byteLength(T)>65536)_.push({key:E,code:"limit",message:`${E} exceeds the portable 64 KiB value limit.`});return _}affectedResources(E,T,_){let d=this.store.list({projectId:E,scope:T}).filter((R)=>_.includes(R.key)).flatMap((R)=>this.store.dependencies(R.id).map((h)=>h.resourceId));if(T.type==="service"||T.type==="function")return hd([...d,T.id]);if(T.type==="environment")return hd([...d,...this.store.controlPlane.listResources(E,T.id).map((R)=>R.id)]);if(T.type==="preview"){let R=this.store.controlPlane.database.query("SELECT resource_id FROM preview_instances WHERE id=?").get(T.id);return hd([...d,...R?[R.resource_id]:[]])}return hd([...d,...this.store.controlPlane.listResources(E).map((R)=>R.id)])}audit(E,T,_,d,R){this.store.controlPlane.appendEvent({projectId:E,actorId:T,type:_,payload:{entryId:d.id,key:d.key,kind:d.kind,scopeType:d.scope.type,scopeId:d.scope.id,backend:d.backend,version:d.version,affectedResourceIds:R}})}}var dq,Rq;var CH=cE(async()=>{Qw();Gw();await d_();dq=/^(?:secret|aws-sm|aws-ssm|vault|doppler|op|external):\/\//,Rq=/^(?:AWS_|TS_CLOUD_|PORT$|HOST$)/});async function Dt(E,T,_,d){let R={added:0,changed:0,removed:0,overridden:0},h=async(r,N)=>{let A=E.store.list({projectId:T.project.id,scope:r,kind:"variable"}),S=new Set(Object.keys(N));for(let L of A.filter((t)=>t.origin==="config"&&!S.has(t.key)))await E.remove({entryId:L.id,expectedVersion:L.version,confirmed:!0,actorId:d}),R.removed++;for(let[L,t]of Object.entries(N)){let O=E.store.find(T.project.id,r,L);if(O?.origin!=="config"){if(O)R.overridden++;else await E.set({organizationId:T.organization.id,projectId:T.project.id,scope:r,key:L,kind:"variable",value:String(t),origin:"config",confirmed:!0,actorId:d}),R.added++;continue}if(O.value===String(t))continue;await E.set({organizationId:T.organization.id,projectId:T.project.id,scope:r,key:L,kind:"variable",value:String(t),origin:"config",confirmed:!0,actorId:d,expectedVersion:O.version}),R.changed++}};for(let[r,N]of Object.entries(_.environments??{})){let A=T.environments.get(r);if(!A)continue;let S=N,L={...S.variables??{},...S.app?.env??{}};await h({type:"environment",id:A.id,environmentId:A.id},L);for(let[t,O]of Object.entries(_.sites??{})){let U=T.store.listResources(T.project.id,A.id).find((D)=>D.kind==="application"&&D.slug===t);if(U)await h({type:"service",id:U.id,environmentId:A.id,resourceId:U.id},{...O.env??{}})}for(let[t,O]of Object.entries(_.infrastructure?.functions??{})){let U=T.store.listResources(T.project.id,A.id).find((D)=>D.kind==="function"&&D.slug===t);if(U)await h({type:"function",id:U.id,environmentId:A.id,resourceId:U.id},{...O.environment??{}})}}return R}var wH={};KT(wH,{synchronizeConfiguredConfiguration:()=>Dt,serializeDotenv:()=>ew,parseDotenv:()=>Yw,LocalEncryptedConfigurationBackend:()=>zr,ExternalConfigurationBackend:()=>gA,ConfigurationStore:()=>ZA,ConfigurationService:()=>vA,AwsSsmConfigurationBackend:()=>xA,AwsSecretsManagerConfigurationBackend:()=>qA});var It=cE(async()=>{Gw();Qw();CH()});function $y(E,T=""){return E===408||E===409||E===425||E===429||E>=500||/rate limit|temporar|timed? ?out|try again/i.test(T)}async function ac(E,T){let _=T?.headers.get("retry-after"),d=_===null||_===void 0?void 0:Number(_)*1000,R=Number.isFinite(d)?Math.max(0,d):Math.min(1000*2**(E-1),30000);await new Promise((h)=>setTimeout(h,R))}var eN;var sc=cE(()=>{eN=class eN{name="porkbun";apiKey;secretKey;requestTimeoutMs;constructor(E,T,_=15000){this.apiKey=E,this.secretKey=T,this.requestTimeoutMs=_}async request(E,T={}){let _;for(let d=1;d<=8;d+=1){let R,h=new AbortController,r=setTimeout(()=>{h.abort(Error(`Porkbun API request timed out after ${this.requestTimeoutMs}ms`))},this.requestTimeoutMs);try{R=await fetch(`https://api.porkbun.com/api/json/v3${E}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...T}),signal:h.signal})}catch(A){if(_=A,d===8)throw A;await ac(d);continue}finally{clearTimeout(r)}if(!R.ok){if(_=Error(`Porkbun API error: ${R.status} ${R.statusText}`),!$y(R.status)||d===8)throw _;await ac(d,R);continue}let N=await R.json();if(N.status==="ERROR"){if(_=Error(`Porkbun API error: ${N.message||"Unknown error"}`),!$y(0,N.message)||d===8)throw _;await ac(d,R);continue}return N}throw _}getSubdomain(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(_===d)return"";if(_.endsWith(`.${d}`))return _.slice(0,-(d.length+1));return _}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}static ADDRESS_TYPES=new Set(["A","AAAA"]);async clearConflictingAliases(E,T){if(!eN.ADDRESS_TYPES.has(T.type))return[];let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return[`could not list records to clear ALIAS/CNAME conflicts: ${R.message??"unknown provider error"}`];let h=[];for(let r of R.records){if(r.type!=="ALIAS"&&r.type!=="CNAME")continue;if(this.getSubdomain(r.name,_)!==d)continue;let N=await this.deleteRecord(E,r);if(!N.success)h.push(`could not remove conflicting ${r.type} on ${r.name}: ${N.message??"unknown provider error"}`)}return h}async addressRecordExists(E,T){let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return!0;return R.records.some((h)=>h.type===T.type&&this.getSubdomain(h.name,_)===d&&h.content===T.content)}async createRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R={type:T.type,content:T.content,ttl:String(T.ttl||600)};if(d)R.name=d;if((T.type==="MX"||T.type==="SRV")&&T.priority!==void 0)R.prio=String(T.priority);if(T.type==="SRV"&&T.weight!==void 0&&T.port!==void 0)R.content=`${T.weight} ${T.port} ${T.content}`;let h=await this.clearConflictingAliases(E,T),r=await this.request(`/dns/create/${_}`,R);if(eN.ADDRESS_TYPES.has(T.type)&&!await this.addressRecordExists(E,T))return{success:!1,message:`Porkbun reported success but no ${T.type} record for ${T.name} exists${h.length>0?` (${h.join("; ")})`:""}. A conflicting ALIAS/CNAME on the same name silently voids the write.`};return{success:!0,id:r.id?.toString(),message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E,T.type);if(R.success){let h=R.records.find((r)=>{return this.getSubdomain(r.name,_)===d&&r.type===T.type});if(h?.id){let r={type:T.type,content:T.content,ttl:String(T.ttl||600)};if(d)r.name=d;if((T.type==="MX"||T.type==="SRV")&&T.priority!==void 0)r.prio=String(T.priority);if(T.type==="SRV"&&T.weight!==void 0&&T.port!==void 0)r.content=`${T.weight} ${T.port} ${T.content}`;return await this.request(`/dns/edit/${_}/${h.id}`,r),{success:!0,id:h.id,message:"Record updated successfully"}}}return this.createRecord(E,T)}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=this.getRootDomain(E);if("id"in T&&T.id)return await this.request(`/dns/delete/${_}/${T.id}`),{success:!0,message:"Record deleted successfully"};let d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return{success:!1,message:"Failed to list records"};let h=R.records.find((r)=>{return this.getSubdomain(r.name,_)===d&&r.type===T.type&&r.content===T.content});if(!h?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${_}/${h.id}`),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=this.getRootDomain(E),d=`/dns/retrieve/${_}`;if(T)d=`/dns/retrieveByNameType/${_}/${T}`;return{success:!0,records:((await this.request(d)).records||[]).map((r)=>({id:r.id,name:r.name||_,type:r.type,content:r.content,ttl:Number.parseInt(r.ttl,10),priority:r.prio?Number.parseInt(r.prio,10):void 0}))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{let T=this.getRootDomain(E);return await this.request(`/dns/retrieve/${T}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((T)=>T.domain)}catch{return[]}}async getNameServers(E){try{let T=this.getRootDomain(E);return(await this.request(`/dns/getNS/${T}`)).ns||[]}catch{return[]}}async updateNameServers(E,T){try{let _=this.getRootDomain(E);return await this.request(`/dns/updateNS/${_}`,{ns:T}),!0}catch{return!1}}}});class Yt{name="godaddy";apiKey;apiSecret;baseUrl;constructor(E,T,_="production"){this.apiKey=E,this.apiSecret=T,this.baseUrl=_==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request(E,T,_){let d=`${this.baseUrl}${T}`,R={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},h={method:E,headers:R};if(_)h.body=JSON.stringify(_);let r=await fetch(d,h);if(r.status===204)return{};if(r.ok){let A=await r.text();if(A)return JSON.parse(A);return{}}let N=`GoDaddy API error: ${r.status} ${r.statusText}`;try{let A=await r.json();if(A.message)N=`GoDaddy API error: ${A.message}`;if(A.fields)N+=` - Fields: ${JSON.stringify(A.fields)}`}catch{}throw Error(N)}getSubdomain(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(_===d)return"@";if(_.endsWith(`.${d}`))return _.slice(0,-(d.length+1));return _}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}toGoDaddyRecord(E,T){let _=this.getRootDomain(T),d=this.getSubdomain(E.name,_),R={type:E.type,name:d,data:E.content,ttl:E.ttl||600};if(E.type==="MX"&&E.priority!==void 0)R.priority=E.priority;return R}fromGoDaddyRecord(E,T){let _=this.getRootDomain(T),d=E.name;if(d==="@")d=_;else if(!d.endsWith(_))d=`${d}.${_}`;return{name:d,type:E.type,content:E.data,ttl:E.ttl,priority:E.priority}}async createRecord(E,T){try{let _=this.getRootDomain(E),d=this.toGoDaddyRecord(T,E);return await this.request("PATCH",`/v1/domains/${_}/records`,[d]),{success:!0,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=this.getRootDomain(E),d=this.toGoDaddyRecord(T,E);return await this.request("PUT",`/v1/domains/${_}/records/${T.type}/${d.name}`,[d]),{success:!0,message:"Record upserted successfully"}}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.request("GET",`/v1/domains/${_}/records/${T.type}/${d}`),h=R.filter((r)=>r.data!==T.content);if(h.length===R.length)return{success:!1,message:"Record not found"};if(h.length===0)try{await this.request("DELETE",`/v1/domains/${_}/records/${T.type}/${d}`)}catch{}else await this.request("PUT",`/v1/domains/${_}/records/${T.type}/${d}`,h);return{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=this.getRootDomain(E),d=`/v1/domains/${_}/records`;if(T)d=`/v1/domains/${_}/records/${T}`;return{success:!0,records:(await this.request("GET",d)).map((h)=>this.fromGoDaddyRecord(h,E))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{let T=this.getRootDomain(E);return await this.request("GET",`/v1/domains/${T}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((T)=>T.domain)}catch{return[]}}async getDomainDetails(E){try{let T=this.getRootDomain(E),_=await this.request("GET",`/v1/domains/${T}`);return{domain:_.domain,status:_.status,nameServers:_.nameServers,expires:_.expires}}catch{return null}}async updateNameServers(E,T){try{let _=this.getRootDomain(E);return await this.request("PUT",`/v1/domains/${_}/records/NS`,T.map((d)=>({type:"NS",name:"@",data:d,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability(E){try{let T=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent(E)}`);return{available:T.available,price:T.price,currency:T.currency}}catch{return{available:!1}}}}class X${name="cloudflare";apiToken;zoneCache=new Map;constructor(E){this.apiToken=E}async request(E,T,_){let d=`https://api.cloudflare.com/client/v4${T}`,R={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},h={method:E,headers:R};if(_)h.body=JSON.stringify(_);let N=await(await fetch(d,h)).json();if(!N.success){let A=N.errors.map((S)=>S.message).join(", ");throw Error(`Cloudflare API error: ${A}`)}return N}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}async getZoneId(E){let T=this.getRootDomain(E),_=this.zoneCache.get(T);if(_)return _;let d=await this.request("GET",`/zones?name=${encodeURIComponent(T)}`);if(!d.result||d.result.length===0)throw Error(`Zone not found for domain: ${T}`);let R=d.result[0].id;return this.zoneCache.set(T,R),R}getFullRecordName(E,T){let _=this.getRootDomain(T),d=E.replace(/\.$/,"");if(!d||d===_||d==="@")return _;if(d.endsWith(`.${_}`))return d;return`${d}.${_}`}toCloudflareRecord(E,T){let _={type:E.type,name:this.getFullRecordName(E.name,T),content:E.content||E.value||"",ttl:E.ttl||1};if(E.type==="MX"&&E.priority!==void 0)_.priority=E.priority;if(E.type==="SRV"){if(E.priority!==void 0)_.priority=E.priority}return _}fromCloudflareRecord(E){return{id:E.id,name:E.name,type:E.type,content:E.content,ttl:E.ttl,priority:E.priority}}async createRecord(E,T){try{let _=await this.getZoneId(E),d=this.toCloudflareRecord(T,E);return{success:!0,id:(await this.request("POST",`/zones/${_}/dns_records`,d)).result.id,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`),h=this.toCloudflareRecord(T,E);if(R.result&&R.result.length>0){let N=R.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${_}/dns_records/${N}`,h)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${_}/dns_records`,h)).result.id,message:"Record created successfully"}}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`);if(!R.result||R.result.length===0)return{success:!1,message:"Record not found"};let h=R.result.find((r)=>r.content===T.content);if(!h)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${_}/dns_records/${h.id}`),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let d=`/zones/${await this.getZoneId(E)}/dns_records?per_page=100`;if(T)d+=`&type=${T}`;let R=[],h=1,r=!0;while(r){let N=await this.request("GET",`${d}&page=${h}`);if(R.push(...N.result||[]),N.result_info)r=h<N.result_info.total_pages,h++;else r=!1}return{success:!0,records:R.map((N)=>this.fromCloudflareRecord(N))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{return await this.getZoneId(E),!0}catch{return!1}}async listDomains(){try{let E=[],T=1,_=!0;while(_){let d=await this.request("GET",`/zones?per_page=50&page=${T}`);if(E.push(...d.result||[]),d.result_info)_=T<d.result_info.total_pages,T++;else _=!1}return E.map((d)=>d.name)}catch{return[]}}async getZoneDetails(E){try{let T=await this.getZoneId(E),_=await this.request("GET",`/zones/${T}`);return{id:_.result.id,name:_.result.name,status:_.result.status,nameServers:_.result.name_servers,paused:_.result.paused}}catch{return null}}async purgeCache(E,T){try{let _=await this.getZoneId(E),d={};if(T?.purgeEverything)d.purge_everything=!0;else{if(T?.files)d.files=T.files;if(T?.tags)d.tags=T.tags;if(T?.hosts)d.hosts=T.hosts}if(Object.keys(d).length===0)d.purge_everything=!0;return await this.request("POST",`/zones/${_}/purge_cache`,d),!0}catch{return!1}}async getRecordProxyStatus(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`);if(R.result&&R.result.length>0)return R.result.find((r)=>r.content===T.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus(E,T,_){try{let d=await this.getZoneId(E),R=this.getFullRecordName(T.name,E),h=await this.request("GET",`/zones/${d}/dns_records?type=${T.type}&name=${encodeURIComponent(R)}`);if(!h.result||h.result.length===0)return!1;let r=h.result.find((N)=>N.content===T.content);if(!r)return!1;return await this.request("PATCH",`/zones/${d}/dns_records/${r.id}`,{proxied:_}),!0}catch{return!1}}}class GN{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor(E="us-east-1",T){this.client=new $_(E),this.providedHostedZoneId=T}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}async getHostedZoneId(E){if(this.providedHostedZoneId)return this.providedHostedZoneId;let T=this.getRootDomain(E),_=this.hostedZoneCache.get(T);if(_)return _;let d=await this.client.findHostedZoneForDomain(E);if(d){let R=d.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(T,R),R}return null}normalizeName(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(!d||d==="@")return`${_}.`;if(d===_||d.endsWith(`.${_}`))return`${d}.`;return`${d}.${_}.`}async createRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async deleteRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,records:[],message:`No hosted zone found for domain: ${E}`};let d=await this.client.listResourceRecordSets({HostedZoneId:_,StartRecordType:T}),R=[];for(let h of d.ResourceRecordSets){if(T&&h.Type!==T)continue;if(h.AliasTarget)continue;for(let r of h.ResourceRecords||[]){let N=r.Value,A;if(h.Type==="MX"){let S=N.split(" ");if(S.length>=2)A=Number.parseInt(S[0],10),N=S.slice(1).join(" ")}if(h.Type==="TXT"&&N.startsWith('"')&&N.endsWith('"'))N=N.slice(1,-1);R.push({name:h.Name.replace(/\.$/,""),type:h.Type,content:N,ttl:h.TTL,priority:A})}}return{success:!0,records:R}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){return await this.getHostedZoneId(E)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((T)=>T.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord(E){try{let T=await this.getHostedZoneId(E.domain);if(!T)return{success:!1,message:`No hosted zone found for domain: ${E.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:T,Name:this.normalizeName(E.domain,E.name),TargetHostedZoneId:E.targetHostedZoneId,TargetDNSName:E.targetDnsName,EvaluateTargetHealth:E.evaluateTargetHealth,Type:E.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(T){return{success:!1,message:T instanceof Error?T.message:"Unknown error"}}}async createCloudFrontAlias(E){return this.createAliasRecord({domain:E.domain,name:E.name,targetHostedZoneId:$_.CloudFrontHostedZoneId,targetDnsName:E.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias(E){let T=$_.ALBHostedZoneIds[E.region];if(!T)return{success:!1,message:`Unknown region for ALB: ${E.region}`};return this.createAliasRecord({domain:E.domain,name:E.name,targetHostedZoneId:T,targetDnsName:E.albDnsName,evaluateTargetHealth:!0})}}var J$=cE(()=>{UN()});var Dy={};KT(Dy,{ACMDnsValidator:()=>et,ACMClient:()=>X_});class X_{client;region;constructor(E="us-east-1"){this.client=new zE,this.region=E}async requestCertificate(E){let T={DomainName:E.DomainName,ValidationMethod:E.ValidationMethod||"DNS"};if(E.SubjectAlternativeNames)T.SubjectAlternativeNames=E.SubjectAlternativeNames;return{CertificateArn:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.RequestCertificate"},body:JSON.stringify(T)})).CertificateArn||""}}async describeCertificate(E){let _=(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DescribeCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})).Certificate||{};return{CertificateArn:_.CertificateArn||"",DomainName:_.DomainName||"",SubjectAlternativeNames:_.SubjectAlternativeNames,Status:_.Status||"PENDING_VALIDATION",Type:_.Type,DomainValidationOptions:_.DomainValidationOptions?.map((d)=>({DomainName:d.DomainName,ValidationDomain:d.ValidationDomain,ValidationStatus:d.ValidationStatus,ResourceRecord:d.ResourceRecord?{Name:d.ResourceRecord.Name,Type:d.ResourceRecord.Type,Value:d.ResourceRecord.Value}:void 0,ValidationMethod:d.ValidationMethod})),CreatedAt:_.CreatedAt,IssuedAt:_.IssuedAt,NotBefore:_.NotBefore,NotAfter:_.NotAfter}}async listCertificates(E){let T={};if(E?.CertificateStatuses)T.CertificateStatuses=E.CertificateStatuses;if(E?.MaxItems)T.MaxItems=E.MaxItems;if(E?.NextToken)T.NextToken=E.NextToken;let _=await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListCertificates"},body:JSON.stringify(T)});return{CertificateSummaryList:(_.CertificateSummaryList||[]).map((d)=>({CertificateArn:d.CertificateArn,DomainName:d.DomainName})),NextToken:_.NextToken}}async deleteCertificate(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DeleteCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})}async listTagsForCertificate(E){return{Tags:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListTagsForCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})).Tags||[]}}async addTagsToCertificate(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.AddTagsToCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn,Tags:E.Tags})})}async resendValidationEmail(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ResendValidationEmail"},body:JSON.stringify({CertificateArn:E.CertificateArn,Domain:E.Domain,ValidationDomain:E.ValidationDomain})})}async findCertificateByDomain(E){let _=(await this.listCertificates({CertificateStatuses:["ISSUED"]})).CertificateSummaryList.find((d)=>d.DomainName===E||d.DomainName===`*.${E.split(".").slice(1).join(".")}`);if(!_)return null;return this.describeCertificate({CertificateArn:_.CertificateArn})}async waitForCertificateValidation(E,T=60,_=30000){for(let d=0;d<T;d++){let R=await this.describeCertificate({CertificateArn:E});if(R.Status==="ISSUED")return R;if(R.Status==="FAILED"||R.Status==="VALIDATION_TIMED_OUT")return null;await new Promise((h)=>setTimeout(h,_))}return null}async getDnsValidationRecords(E){let T=await this.describeCertificate({CertificateArn:E});if(!T.DomainValidationOptions)return[];return T.DomainValidationOptions.filter((_)=>_.ResourceRecord&&_.ValidationMethod==="DNS").map((_)=>({domainName:_.DomainName,recordName:_.ResourceRecord.Name,recordType:_.ResourceRecord.Type,recordValue:_.ResourceRecord.Value}))}async requestCertificateWithSans(E){let T=new Set;if(T.add(E.DomainName),E.IncludeWww!==!1)T.add(`www.${E.DomainName}`);if(E.IncludeWildcard)T.add(`*.${E.DomainName}`);if(E.AdditionalSans)for(let _ of E.AdditionalSans)T.add(_);return this.requestCertificate({DomainName:E.DomainName,SubjectAlternativeNames:Array.from(T),ValidationMethod:"DNS"})}async isCertificateValidForDomain(E,T){let _=await this.describeCertificate({CertificateArn:E});if(_.Status!=="ISSUED")return!1;if(_.DomainName===T)return!0;if(_.DomainName?.startsWith("*.")){let d=_.DomainName.slice(2),R=T.split("."),h=d.split(".");if(R.slice(-h.length).join(".")===d)return!0}if(_.SubjectAlternativeNames)for(let d of _.SubjectAlternativeNames){if(d===T)return!0;if(d.startsWith("*.")){let R=d.slice(2),h=T.split("."),r=R.split(".");if(h.slice(-r.length).join(".")===R)return!0}}return!1}}class et{acm;route53;dnsProvider;constructor(E="us-east-1",T){if(this.acm=new X_(E),this.route53=new $_,T&&T.provider!=="route53")this.dnsProvider=Y_(T)}async requestAndValidate(E){let{domainName:T,hostedZoneId:_,subjectAlternativeNames:d=[],waitForValidation:R=!1,maxWaitMinutes:h=30}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let{CertificateArn:r}=await this.acm.requestCertificate({DomainName:T,SubjectAlternativeNames:d.length>0?[T,...d]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(r);let N=await this.acm.getDnsValidationRecords(r);if(this.dnsProvider)for(let A of N){let S=await this.dnsProvider.upsertRecord(T,{name:A.recordName,type:A.recordType,content:A.recordValue,ttl:300});if(!S.success)console.warn(`Failed to create validation record for ${A.domainName}: ${S.message}`)}else if(_)for(let A of N)await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`ACM DNS validation for ${A.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:A.recordName,Type:A.recordType,TTL:300,ResourceRecords:[{Value:A.recordValue}]}}]}});if(R){if(!await this.acm.waitForCertificateValidation(r,h*2,30000))throw Error(`Certificate validation timed out after ${h} minutes`)}return{certificateArn:r,validationRecords:N}}async waitForValidationOptions(E,T=30){for(let _=0;_<T;_++){let d=await this.acm.describeCertificate({CertificateArn:E});if(d.DomainValidationOptions&&d.DomainValidationOptions.length>0&&d.DomainValidationOptions[0].ResourceRecord)return;await new Promise((R)=>setTimeout(R,2000))}throw Error("Timeout waiting for DNS validation options")}async createValidationRecords(E){let{certificateArn:T,hostedZoneId:_,domain:d}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let R=await this.acm.getDnsValidationRecords(T),h=[];if(this.dnsProvider){let r=d||R[0]?.domainName;for(let N of R){let A=await this.dnsProvider.upsertRecord(r,{name:N.recordName,type:N.recordType,content:N.recordValue,ttl:300});h.push({...N,changeId:A.success?A.id:void 0})}}else if(_)for(let r of R){let N=await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`ACM DNS validation for ${r.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:r.recordName,Type:r.recordType,TTL:300,ResourceRecords:[{Value:r.recordValue}]}}]}});h.push({...r,changeId:N.ChangeInfo?.Id})}return h}async deleteValidationRecords(E){let{certificateArn:T,hostedZoneId:_,domain:d}=E,R=await this.acm.getDnsValidationRecords(T);if(this.dnsProvider){let h=d||R[0]?.domainName;for(let r of R)try{await this.dnsProvider.deleteRecord(h,{name:r.recordName,type:r.recordType,content:r.recordValue})}catch{}}else if(_)for(let h of R)try{await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`Cleanup ACM DNS validation for ${h.domainName}`,Changes:[{Action:"DELETE",ResourceRecordSet:{Name:h.recordName,Type:h.recordType,TTL:300,ResourceRecords:[{Value:h.recordValue}]}}]}})}catch{}}async findOrCreateCertificate(E){let{domainName:T,hostedZoneId:_,subjectAlternativeNames:d,waitForValidation:R=!0}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let h=await this.acm.findCertificateByDomain(T);if(h&&h.Status==="ISSUED")return{certificateArn:h.CertificateArn,isNew:!1};let{certificateArn:r}=await this.requestAndValidate({domainName:T,hostedZoneId:_,subjectAlternativeNames:d,waitForValidation:R});return{certificateArn:r,isNew:!0}}hasExternalDnsProvider(){return this.dnsProvider!==void 0}getDnsProviderName(){return this.dnsProvider?.name||"route53"}}var Bh=cE(()=>{VE();UN();gR()});class QN{acm;dnsProvider;constructor(E,T="us-east-1"){if(this.acm=new X_(T),"provider"in E)this.dnsProvider=Y_(E);else this.dnsProvider=E}getProvider(){return this.dnsProvider}async requestAndValidate(E){let{domainName:T,subjectAlternativeNames:_=[],waitForValidation:d=!1,maxWaitMinutes:R=30}=E,{CertificateArn:h}=await this.acm.requestCertificate({DomainName:T,SubjectAlternativeNames:_.length>0?[T,..._]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(h);let r=await this.acm.getDnsValidationRecords(h);for(let A of r){let S=await this.dnsProvider.upsertRecord(T,{name:A.recordName,type:A.recordType,content:A.recordValue,ttl:300});if(!S.success)console.warn(`Failed to create validation record for ${A.domainName}: ${S.message}`)}let N="pending";if(d)N=(await this.acm.waitForCertificateValidation(h,R*2,30000))?.Status==="ISSUED"?"issued":"failed";return{certificateArn:h,validationRecords:r.map((A)=>({domainName:A.domainName,recordName:A.recordName,recordType:A.recordType,recordValue:A.recordValue})),isNew:!0,status:N}}async createValidationRecords(E){let{certificateArn:T,domain:_}=E,d=[],R=await this.acm.getDnsValidationRecords(T);for(let h of R){let r=await this.dnsProvider.upsertRecord(_,{name:h.recordName,type:h.recordType,content:h.recordValue,ttl:300});if(!r.success)d.push(`Failed to create record for ${h.domainName}: ${r.message}`)}return{success:d.length===0,records:R.map((h)=>({domainName:h.domainName,recordName:h.recordName,recordType:h.recordType,recordValue:h.recordValue})),errors:d}}async deleteValidationRecords(E){let{certificateArn:T,domain:_}=E,d=[],R=await this.acm.getDnsValidationRecords(T);for(let h of R){let r=await this.dnsProvider.deleteRecord(_,{name:h.recordName,type:h.recordType,content:h.recordValue});if(!r.success)d.push(`Failed to delete record for ${h.domainName}: ${r.message}`)}return{success:d.length===0,errors:d}}async findOrCreateCertificate(E){let{domainName:T,subjectAlternativeNames:_=[],waitForValidation:d=!0,maxWaitMinutes:R}=E,h=await this.acm.findCertificateByDomain(T);if(h&&h.Status==="ISSUED"){let r=h.SubjectAlternativeNames||[h.DomainName],N=r.some((S)=>S===`*.${T}`);if(_.every((S)=>r.includes(S)||N))return{certificateArn:h.CertificateArn,validationRecords:[],isNew:!1,status:"issued"};console.log("Existing certificate doesn't cover all required SANs, requesting new certificate...")}return this.requestAndValidate({domainName:T,subjectAlternativeNames:_,waitForValidation:d,maxWaitMinutes:R})}async requestCertificateWithCommonSans(E){let{domainName:T,includeWww:_=!0,includeWildcard:d=!1,additionalSans:R=[],waitForValidation:h=!1}=E,r=[];if(_)r.push(`www.${T}`);if(d)r.push(`*.${T}`);return r.push(...R),this.requestAndValidate({domainName:T,subjectAlternativeNames:r,waitForValidation:h})}async waitForValidationOptions(E,T=30){for(let _=0;_<T;_++){let d=await this.acm.describeCertificate({CertificateArn:E});if(d.DomainValidationOptions&&d.DomainValidationOptions.length>0&&d.DomainValidationOptions[0].ResourceRecord)return;await new Promise((R)=>setTimeout(R,2000))}throw Error("Timeout waiting for DNS validation options")}async getCertificateStatus(E){let T=await this.acm.describeCertificate({CertificateArn:E});return{status:T.Status,domainValidations:(T.DomainValidationOptions||[]).map((_)=>({domain:_.DomainName,status:_.ValidationStatus||"UNKNOWN"}))}}}var pc=cE(()=>{Bh();gR()});function Y_(E){switch(E.provider){case"route53":return new GN(E.region,E.hostedZoneId);case"porkbun":return new eN(E.apiKey,E.secretKey);case"godaddy":return new Yt(E.apiKey,E.apiSecret,E.environment);case"cloudflare":return new X$(E.apiToken);default:throw Error(`Unknown DNS provider: ${E.provider}`)}}class Gt{providers=new Map;configs=[];addConfig(E){return this.configs.push(E),this}addRoute53(E,T){return this.configs.push({provider:"route53",region:E,hostedZoneId:T}),this}addPorkbun(E,T){return this.configs.push({provider:"porkbun",apiKey:E,secretKey:T}),this}addGoDaddy(E,T,_){return this.configs.push({provider:"godaddy",apiKey:E,apiSecret:T,environment:_}),this}addCloudflare(E){return this.configs.push({provider:"cloudflare",apiToken:E}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let E=process.env.PORKBUN_API_KEY,T=process.env.PORKBUN_SECRET_KEY;if(E&&T)this.addPorkbun(E,T);let _=process.env.GODADDY_API_KEY,d=process.env.GODADDY_API_SECRET;if(_&&d){let h=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(_,d,h)}let R=process.env.CLOUDFLARE_API_TOKEN;if(R)this.addCloudflare(R);return this}getProvider(E){let T=this.providers.get(E);if(T)return T;let _=this.configs.find((R)=>R.provider===E);if(!_)return null;let d=Y_(_);return this.providers.set(E,d),d}async getProviderForDomain(E){for(let T of this.configs){let _=Y_(T);if(await _.canManageDomain(E))return _}return null}getAllProviders(){return this.configs.map((E)=>Y_(E))}}var L3;var gR=cE(()=>{sc();J$();pc();sc();J$();L3=new Gt});var hX={};KT(hX,{CloudFormationClient:()=>oE});class oE{client;region;constructor(E="us-east-1",T){this.region=E,this.client=new zE(void 0,{profile:T})}async createStack(E){let T={Action:"CreateStack",StackName:E.stackName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(E.parameters)E.parameters.forEach((d,R)=>{T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.roleArn)T.RoleARN=E.roleArn;if(E.tags)E.tags.forEach((d,R)=>{T[`Tags.member.${R+1}.Key`]=d.Key,T[`Tags.member.${R+1}.Value`]=d.Value});if(E.timeoutInMinutes)T.TimeoutInMinutes=E.timeoutInMinutes;if(E.onFailure)T.OnFailure=E.onFailure;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackId:_.StackId||_.CreateStackResult?.StackId}}async updateStack(E){let T={Action:"UpdateStack",StackName:E.stackName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;if(E.parameters)E.parameters.forEach((d,R)=>{if(T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,d.UsePreviousValue)T[`Parameters.member.${R+1}.UsePreviousValue`]="true";else T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.roleArn)T.RoleARN=E.roleArn;if(E.tags)E.tags.forEach((d,R)=>{T[`Tags.member.${R+1}.Key`]=d.Key,T[`Tags.member.${R+1}.Value`]=d.Value});let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackId:_.StackId||_.UpdateStackResult?.StackId}}async deleteStack(E,T,_){let d={Action:"DeleteStack",StackName:E,Version:"2010-05-15"};if(T)d.RoleARN=T;if(_&&_.length>0)_.forEach((R,h)=>{d[`RetainResources.member.${h+1}`]=R});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(d).toString()})}async describeStacks(E={}){let T={Action:"DescribeStacks",Version:"2010-05-15"};if(E.stackName)T.StackName=E.stackName;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{Stacks:this.parseStacksResponse(_)}}async describeStackEvents(E){let T={Action:"DescribeStackEvents",StackName:E,Version:"2010-05-15"},_=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackEvents:this.parseStackEvents(_)}}async listStackResources(E){let T={Action:"ListStackResources",StackName:E,Version:"2010-05-15"},d=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,R=[];if(d)R=Array.isArray(d)?d:[d];return{StackResourceSummaries:R}}async waitForStack(E,T){let _={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},d=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],R=_[T],h=360,r=0;while(r<360)try{let N=await this.describeStacks({stackName:E});if(N.Stacks.length===0){if(T==="stack-delete-complete")return;if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Stack not visible yet`);await new Promise((S)=>setTimeout(S,2000)),r++;continue}let A=N.Stacks[0];if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Status = ${A.StackStatus}${A.StackStatusReason?` (${A.StackStatusReason})`:""}`);if(R.includes(A.StackStatus))return;if((T==="stack-create-complete"||T==="stack-update-complete")&&(A.StackStatus==="DELETE_IN_PROGRESS"||A.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let S="";try{let t=await this.describeStackEvents(E);console.log("[waitForStack] Stack events (most recent first):");for(let O of t.StackEvents.slice(0,15))if(O.ResourceStatus.includes("FAILED")||O.ResourceStatusReason){if(console.log(` ${O.LogicalResourceId}: ${O.ResourceStatus} - ${O.ResourceStatusReason||"No reason provided"}`),O.ResourceStatus.includes("FAILED")&&O.ResourceStatusReason&&!S)S=O.ResourceStatusReason}}catch{}let L=S||A.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${L}`)}if(A.StackStatus==="DELETE_FAILED"&&T==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=A.StackStatus,S.statusReason=A.StackStatusReason,S}if(d.includes(A.StackStatus))throw Error(`Stack reached failure status: ${A.StackStatus}`);await new Promise((S)=>setTimeout(S,5000)),r++}catch(N){if(T==="stack-delete-complete"&&N.message?.includes("does not exist"))return;if(T==="stack-create-complete"&&N.message?.includes("does not exist")){if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Stack does not exist (error), retrying...`);await new Promise((A)=>setTimeout(A,2000)),r++;continue}throw console.log(`[waitForStack] Unexpected error: ${N.message}`),N}throw console.log(`[waitForStack] Timeout after ${r} attempts`),Error(`Timeout waiting for stack to reach ${T}`)}async validateTemplate(E){let T={Action:"ValidateTemplate",TemplateBody:E,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()})}async listStacks(E){let T={Action:"ListStacks",Version:"2010-05-15"};if(E)E.forEach((N,A)=>{T[`StackStatusFilter.member.${A+1}`]=N});let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()}),d=_.ListStacksResponse||_,R=d.ListStacksResult||d,h=R.StackSummaries?.member||R.StackSummaries||[];return{StackSummaries:(Array.isArray(h)?h:h?[h]:[]).map((N)=>({StackId:N.StackId||"",StackName:N.StackName||"",TemplateDescription:N.TemplateDescription,CreationTime:N.CreationTime||"",LastUpdatedTime:N.LastUpdatedTime,DeletionTime:N.DeletionTime,StackStatus:N.StackStatus||""}))}}async createChangeSet(E){let T={Action:"CreateChangeSet",StackName:E.stackName,ChangeSetName:E.changeSetName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;if(E.parameters)E.parameters.forEach((d,R)=>{T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.changeSetType)T.ChangeSetType=E.changeSetType;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{Id:_.Id,StackId:_.StackId}}async describeChangeSet(E,T){let _={Action:"DescribeChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async executeChangeSet(E,T){let _={Action:"ExecuteChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async deleteChangeSet(E,T){let _={Action:"DeleteChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async getStackOutputs(E){let T=await this.describeStacks({stackName:E});if(!T.Stacks||T.Stacks.length===0)throw Error(`Stack ${E} not found`);let _=T.Stacks[0],d={};if(_.Outputs)for(let R of _.Outputs)d[R.OutputKey]=R.OutputValue;return d}async getTemplate(E){let T={Action:"GetTemplate",StackName:E,Version:"2010-05-15"},_=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{TemplateBody:_?.GetTemplateResult?.TemplateBody||_?.TemplateBody||""}}parseStacksResponse(E){let T=[],_=E?.DescribeStacksResult?.Stacks?.member||E?.Stacks?.member||E?.Stacks||E;if(_&&!Array.isArray(_))_=[_];if(Array.isArray(_)){for(let d of _)if(d.StackId||d.StackName){let R;if(d.Outputs?.member)R=(Array.isArray(d.Outputs.member)?d.Outputs.member:[d.Outputs.member]).map((r)=>({OutputKey:r.OutputKey,OutputValue:r.OutputValue,Description:r.Description,ExportName:r.ExportName}));T.push({StackId:d.StackId,StackName:d.StackName,StackStatus:d.StackStatus,CreationTime:d.CreationTime,LastUpdatedTime:d.LastUpdatedTime,StackStatusReason:d.StackStatusReason,Outputs:R})}}else if(E.StackId)T.push({StackId:E.StackId,StackName:E.StackName,StackStatus:E.StackStatus,CreationTime:E.CreationTime,LastUpdatedTime:E.LastUpdatedTime});return T}parseStackEvents(E){let T=[],_=E?.DescribeStackEventsResult?.StackEvents?.member||E?.StackEvents?.member||E?.StackEvents||[];if(_&&!Array.isArray(_))_=[_];for(let d of _)if(d.LogicalResourceId)T.push({Timestamp:d.Timestamp,ResourceType:d.ResourceType,LogicalResourceId:d.LogicalResourceId,ResourceStatus:d.ResourceStatus,ResourceStatusReason:d.ResourceStatusReason});return T}async waitForStackWithProgress(E,T,_){let d={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},R=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],h=d[T],r=360,N=0,A=new Set;while(N<360)try{if(_)try{let O=[...(await this.describeStackEvents(E)).StackEvents||[]].reverse();for(let U of O){let D=`${U.LogicalResourceId}-${U.ResourceStatus}-${U.Timestamp}`;if(!A.has(D))A.add(D),_({resourceId:U.LogicalResourceId,resourceType:U.ResourceType,status:U.ResourceStatus,reason:U.ResourceStatusReason,timestamp:U.Timestamp})}}catch{}let S=await this.describeStacks({stackName:E});if(S.Stacks.length===0){if(T==="stack-delete-complete")return;await new Promise((t)=>setTimeout(t,2000)),N++;continue}let L=S.Stacks[0];if(h.includes(L.StackStatus))return;if(L.StackStatus==="DELETE_FAILED"&&T==="stack-delete-complete"){let t=Error("Stack deletion failed - may have resources that need to be retained");throw t.code="DELETE_FAILED",t.stackStatus=L.StackStatus,t.statusReason=L.StackStatusReason,t}if(R.includes(L.StackStatus))throw Error(`Stack reached failure status: ${L.StackStatus}`);await new Promise((t)=>setTimeout(t,3000)),N++}catch(S){if(T==="stack-delete-complete"&&S.message?.includes("does not exist"))return;if(T==="stack-create-complete"&&S.message?.includes("does not exist")){await new Promise((L)=>setTimeout(L,2000)),N++;continue}throw S}throw Error(`Timeout waiting for stack to reach ${T}`)}async waitForStackComplete(E,T=120,_=5000){let d=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],R=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let h=0;h<T;h++)try{let r=await this.describeStacks({stackName:E});if(r.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let N=r.Stacks[0],A=N.StackStatus;if(d.includes(A))return{success:!0,status:A};if(R.includes(A))return{success:!1,status:A,reason:N.StackStatusReason};await new Promise((S)=>setTimeout(S,_))}catch(r){if(r.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw r}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}var e_=cE(()=>{VE()});import{homedir as Q3}from"node:os";import{join as M3}from"node:path";function Hy(E){return E.startsWith("~/")?M3(Q3(),E.slice(2)):E}function OS(...E){for(let T of E){let _=process.env[T]?.trim();if(_)return _}return}function US(...E){for(let T of E){let _=T?.trim();if(_)return _}return}function AX(E,T){return US(E,T?.hetzner?.apiToken,OS("HCLOUD_TOKEN","HETZNER_API_TOKEN"))}function SX(E,T){return US(T,E?.hetzner?.location,OS("HCLOUD_LOCATION","HETZNER_LOCATION"))??B$.location}function Kt(E,T){let _=E?.infrastructure?.compute;return US(T,_?.image,E?.hetzner?.image,OS("HCLOUD_IMAGE","HETZNER_IMAGE"))??B$.image}function V3(E,T){return US(T,E?.hetzner?.sshUser,OS("HCLOUD_SSH_USER","HETZNER_SSH_USER"))??B$.sshUser}function yy(E,T){return Hy(US(T,E?.hetzner?.sshPrivateKeyPath,OS("HCLOUD_SSH_KEY","HETZNER_SSH_KEY"))??B$.sshPrivateKeyPath)}function K3(E,T,_){let d=US(T,E?.hetzner?.sshPublicKeyPath,OS("HCLOUD_SSH_PUBLIC_KEY","HETZNER_SSH_PUBLIC_KEY"));if(d)return Hy(d);return`${_??yy(E)}.pub`}function $S(E,T={}){let _=yy(E,T.sshPrivateKeyPath);return{apiToken:AX(T.apiToken,E),location:SX(E,T.location),image:Kt(E,T.image),sshUser:V3(E,T.sshUser),sshPrivateKeyPath:_,sshPublicKeyPath:K3(E,T.sshPublicKeyPath,_)}}var B$;var ft=cE(()=>{B$={location:"fsn1",image:"ubuntu-24.04",sshUser:"root",sshPrivateKeyPath:"~/.ssh/id_ed25519"}});class Wh{name="hetzner";apiToken;baseUrl;fetchImpl;constructor(E){this.apiToken=E.apiToken,this.baseUrl=E.baseUrl??f3,this.fetchImpl=E.fetchImpl??fetch}async request(E,T,_){let d=await this.fetchImpl(`${this.baseUrl}${T}`,{method:E,headers:{Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},body:_===void 0?void 0:JSON.stringify(_)}),R=await d.text(),h;try{h=R?JSON.parse(R):{}}catch{if(!d.ok){let r=R.trim().slice(0,200)||d.statusText||"Hetzner API error";throw Error(`Hetzner API ${E} ${T} (${d.status}): ${r}`)}throw Error(`Hetzner API ${E} ${T}: unexpected non-JSON response`)}if(!d.ok){let r=h.error?.message||d.statusText||"Hetzner API error",N=h.error?.code?` [${h.error.code}]`:"";throw new W$(`Hetzner API ${E} ${T} (${d.status})${N}: ${r}`,d.status,h.error?.code,h.error?.details)}return h}async requestAll(E,T){let _=[],d=1;for(;;){let R=E.includes("?")?"&":"?",h=await this.request("GET",`${E}${R}per_page=50&page=${d}`);_.push(...h[T]??[]);let r=h.meta?.pagination?.next_page;if(!r)return _;d=r}}async listServers(){return this.requestAll("/servers","servers")}async getServer(E){return(await this.request("GET",`/servers/${E}`)).server}async getServerMetrics(E,T){let _=new URLSearchParams({type:T.types.join(","),start:T.start.toISOString(),end:T.end.toISOString(),step:String(Math.max(60,Math.floor(T.step??60)))});return(await this.request("GET",`/servers/${E}/metrics?${_}`)).metrics}async listServerTypes(E){let T=E?`?name=${encodeURIComponent(E)}`:"";return this.requestAll(`/server_types${T}`,"server_types")}async getServerType(E){return(await this.listServerTypes(E)).find((T)=>T.name===E)??null}async createServer(E){let T=await this.request("POST","/servers",{name:E.name,server_type:E.serverType,image:E.image,location:E.location,datacenter:E.datacenter,ssh_keys:E.sshKeys,user_data:E.userData,labels:E.labels,firewalls:E.firewalls,networks:E.networks,start_after_create:!0});return{server:T.server,action:T.action}}async listNetworks(){return this.requestAll("/networks","networks")}async createNetwork(E){let T=E.ipRange??"10.0.0.0/16";return(await this.request("POST","/networks",{name:E.name,ip_range:T,subnets:[{type:"cloud",ip_range:T,network_zone:"eu-central"}],labels:E.labels})).network}async deleteNetwork(E){await this.request("DELETE",`/networks/${E}`)}async listLoadBalancers(){return this.requestAll("/load_balancers","load_balancers")}async createLoadBalancer(E){return(await this.request("POST","/load_balancers",{name:E.name,load_balancer_type:E.type??"lb11",location:E.location,network_zone:E.network?void 0:E.networkZone??"eu-central",network:E.network,labels:E.labels,targets:[{type:"label_selector",label_selector:{selector:E.labelSelector},use_private_ip:!!E.network}],services:E.services.map((_)=>({protocol:_.protocol??"tcp",listen_port:_.listenPort,destination_port:_.destinationPort,health_check:{protocol:"http",port:80,interval:15,timeout:10,retries:3,http:{path:"/",status_codes:["2??","3??"]}}}))})).load_balancer}async deleteLoadBalancer(E){await this.request("DELETE",`/load_balancers/${E}`)}async deleteServer(E){return(await this.request("DELETE",`/servers/${E}`)).action}async listFirewalls(){return this.requestAll("/firewalls","firewalls")}async createFirewall(E){let T=await this.request("POST","/firewalls",{name:E.name,rules:E.rules,labels:E.labels,apply_to:E.applyTo});return{firewall:T.firewall,actions:T.actions}}async setFirewallRules(E,T){return(await this.request("POST",`/firewalls/${E}/actions/set_rules`,{rules:T})).actions??[]}async deleteFirewall(E){await this.request("DELETE",`/firewalls/${E}`)}async applyFirewallToResources(E,T){return(await this.request("POST",`/firewalls/${E}/actions/apply_to_resources`,{apply_to:T})).actions}async listSshKeys(){return this.requestAll("/ssh_keys","ssh_keys")}async createSshKey(E){return(await this.request("POST","/ssh_keys",{name:E.name,public_key:E.publicKey,labels:E.labels})).ssh_key}async getAction(E){return(await this.request("GET",`/actions/${E}`)).action}async shutdownServer(E){return(await this.request("POST",`/servers/${E}/actions/shutdown`,{})).action}async powerOnServer(E){return(await this.request("POST",`/servers/${E}/actions/poweron`,{})).action}async changeServerType(E,T,_){return(await this.request("POST",`/servers/${E}/actions/change_type`,{server_type:T,upgrade_disk:_})).action}async waitForAction(E,T){let _=T?.pollIntervalMs??2000,d=T?.maxWaitMs??300000,R=Date.now();while(Date.now()-R<d){let h=await this.getAction(E);if(h.status==="success")return h;if(h.status==="error")throw new H$(h.error?.message||"Hetzner action failed",h);await new Promise((r)=>setTimeout(r,_))}throw Error(`Timed out waiting for Hetzner action ${E}`)}async waitForServerRunning(E,T){let _=T?.pollIntervalMs??3000,d=T?.maxWaitMs??600000,R=Date.now();while(Date.now()-R<d){let h=await this.getServer(E);if(h.status==="running")return h;await new Promise((r)=>setTimeout(r,_))}throw Error(`Timed out waiting for server ${E} to reach running state`)}async waitForServerStatus(E,T,_){let d=_?.pollIntervalMs??3000,R=_?.maxWaitMs??600000,h=Date.now();while(Date.now()-h<R){let r=await this.getServer(E);if(r.status===T)return r;await new Promise((N)=>setTimeout(N,d))}throw Error(`Timed out waiting for server ${E} to reach ${T} state`)}}function Qr(E,T){let _=AX(E,T);if(!_)throw Error("Hetzner API token required. Set hetzner.apiToken in cloud.config.ts or HCLOUD_TOKEN / HETZNER_API_TOKEN.");return _}function DS(E){let[T,_]=E.trim().split(/\s+/);return _?`${T} ${_}`:T}var f3="https://api.hetzner.cloud/v1",W$,H$;var IS=cE(()=>{ft();W$=class W$ extends Error{status;code;details;constructor(E,T,_,d){super(E);this.status=T;this.code=_;this.details=d;this.name="HetznerApiError"}};H$=class H$ extends Error{action;constructor(E,T){super(E);this.action=T;this.name="HetznerActionError"}}});function CS(E){let T=new Set([80,443,...E.sitePorts,...E.allowedPorts??[]]);if(E.allowSsh)T.add(22);return[...T].map((_)=>{return{direction:"in",protocol:"tcp",port:String(_),source_ips:["0.0.0.0/0","::/0"],description:`ts-cloud port ${_}`}})}function LX(E={}){let T=[];if(E.identityFile)T.push("-i",E.identityFile);return T.push("-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null","-o","LogLevel=ERROR","-o",`ConnectTimeout=${E.connectTimeoutSec??10}`),T}async function y$(E,T,_={}){let d=Bun.spawn(["ssh",...LX(_),`${_.user??"root"}@${E}`,T],{stdout:"pipe",stderr:"pipe"}),[R,h]=await Promise.all([new Response(d.stdout).text(),new Response(d.stderr).text()]);return{code:await d.exited,stdout:R,stderr:h}}async function id(E,T,_={}){let d=await y$(E,T,_);if(d.code!==0)throw Error(`ssh \`${T}\` on ${E} failed (${d.code}): ${d.stderr.trim()||d.stdout.trim()}`);return d.stdout}async function Y$(E,T={}){let _=T.timeoutMs??180000,d=T.pollIntervalMs??5000,R=Date.now();while(Date.now()-R<_){let h=await y$(E,"echo ready",T);if(h.code===0&&h.stdout.includes("ready"))return;await new Promise((r)=>setTimeout(r,d))}throw Error(`SSH not ready on ${E} after ${_}ms`)}function Vr(E=!0){if(!E)return[];return["export DEBIAN_FRONTEND=noninteractive","dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q 'ok installed' || apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable --now unattended-upgrades 2>/dev/null || true"]}function g3(E=!0){let T=typeof E==="object"?E:{};return{enabled:typeof E==="boolean"?E:E.enabled!==!1,cpuLoadPerCore:T.alerts?.cpuLoadPerCore??2,memPercent:T.alerts?.memPercent??90,diskPercent:T.alerts?.diskPercent??90}}function Kr(E=!0){let{enabled:T,cpuLoadPerCore:_,memPercent:d,diskPercent:R}=g3(E);if(!T)return[];let h=Gy.map(([N,A])=>`SVC_${N.toUpperCase()}=$(probe ${A})`),r=Gy.map(([N])=>`"${N}":"$SVC_${N.toUpperCase()}"`).join(",");return["if ! command -v sadf >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -y -qq sysstat; fi","systemctl enable --now sysstat.service 2>/dev/null || true","mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...h,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+r+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${_} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${_}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${d} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${R} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnCalendar=*-*-* *:*:00","AccuracySec=1s","RandomizedDelaySec=5s","Persistent=true","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable --now ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.service"]}var Gy;var Pt=cE(()=>{Gy=[["nginx",80],["https",443],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700],["typesense",8108],["smtp",25]]});function md(E,T){return`/var/www/${E}-${T}`}function Zt(E){return E.type!=null&&b3.has(E.type)}function UX(E){if(E.deploy)return E.deploy;if(Zt(E))return"server";if(E.start)return"server";return"bucket"}function vT(E){if(E.redirect)return"redirect";if(Zt(E))return"server-php";if(UX(E)==="bucket")return"bucket";return E.start?"server-app":"server-static"}function k3(E){return E.infrastructure?.compute!=null}function $X(E){let T=[],_=[],d=E.sites||{},R=k3(E),h=fA(E);if(h)T.push(h);let r=new Map;for(let[N,A]of Object.entries(d)){if(!A)continue;let S=UX(A),L=vT(A);if(L==="redirect"){if(!A.domain)T.push(`Site '${N}' is a redirect site but has no \`domain\` to redirect from.`);if(!(typeof A.redirect==="string"?A.redirect:A.redirect?.to))T.push(`Site '${N}' is a redirect site but has no redirect target (\`redirect\` / \`redirect.to\`).`);if(!R)T.push(`Site '${N}' is a redirect site but no \`infrastructure.compute\` is configured to host the gateway that serves the redirect.`);let O=[];if(A.start)O.push("start");if(A.root)O.push("root");if(O.length>0)_.push(`Site '${N}' is a redirect site but also sets ${O.join(", ")}. These are ignored.`);continue}if(S==="server"&&!A.start&&!A.root){T.push(`Site '${N}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);continue}if(L==="server-php"){if(!R)T.push(`Site '${N}' is a PHP site (type:'${A.type}') but no \`infrastructure.compute\` is configured. Add a server (infrastructure.compute) with PHP provisioning.`);if(!A.repository?.url)T.push(`Site '${N}' is a PHP site (type:'${A.type}') but has no \`repository.url\` to clone. PHP sites deploy via git.`)}else if(L==="server-app"){if(!R)T.push(`Site '${N}' deploys to a server (deploy:'server'${A.deploy?"":" inferred from `start`"}) but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`);if(typeof A.port==="number"){let t=r.get(A.port);if(t)T.push(`Sites '${t}' and '${N}' both use port ${A.port}. Server apps sharing a box must use distinct ports.`);else r.set(A.port,N)}}else if(L==="server-static"){if(!A.root)T.push(`Site '${N}' is a server static site (deploy:'server', no \`start\`) but has no \`root\` directory to serve.`);if(!R)T.push(`Site '${N}' deploys to a server (deploy:'server') but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`)}else{if(!A.root)T.push(`Site '${N}' deploys to a bucket but has no \`root\` directory to upload.`);let t=[];if(A.start)t.push("start");if(typeof A.port==="number")t.push("port");if(A.preStart&&A.preStart.length>0)t.push("preStart");if(t.length>0)_.push(`Site '${N}' deploys to a bucket but sets server-only field(s): ${t.join(", ")}. These are ignored. Set deploy:'server' to use them.`)}}return{errors:T,warnings:_}}function Qy(E){let T=vT(E);return T!=="bucket"&&T!=="redirect"}var b3;var fr=cE(async()=>{await mE();b3=new Set(["laravel","php","statamic","wordpress"])});function v3(E){if(typeof E==="string")return{to:E};let T={to:E.to};if(E.status!=null)T.status=E.status;if(E.preservePath!=null)T.preservePath=E.preservePath;return T}function n3(E){let T=E.auth;if(!T||T.enabled===!1||!T.password)return;return{username:T.username||"admin",password:T.password,...T.realm?{realm:T.realm}:{}}}function My(E){if(!E||E==="/")return;let T=`/${E}`.replace(/\/+/g,"/").replace(/\/+$/,"");if(!T.startsWith("/"))T=`/${T}`;return T===""||T==="/"?void 0:T}function DX(E,T){let d=(T?`${E}${T}`:E).replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return d.length>0?d:"rpx"}function l3(E,T){if(!T||T.length===0)return`localhost:${E}`;return T.map((_)=>`${_.privateIp??_.publicIp}:${E}`)}function Vy(E,T,_){let d=(T.wwwRoot??"/var/www").replace(/\/+$/,""),R=T.slug??"app",h=T.proxy.certsDir??CX,r=T.proxy.loadBalancer,N=[],A=new Set;for(let[t,O]of Object.entries(E)){if(!O||!O.domain)continue;let U=vT(O);if(U==="bucket")continue;let D=My(O.path),C=DX(O.domain,D),w=n3(O);if(U==="redirect"){N.push({to:O.domain,path:D,redirect:v3(O.redirect),id:C,...w?{auth:w}:{}}),A.add(O.domain);continue}if(U==="server-app"){if(typeof O.port!=="number")continue;let c=l3(O.port,_);N.push({to:O.domain,path:D,from:c,id:C,...w?{auth:w}:{},...Array.isArray(c)&&r?{loadBalancer:r}:{}})}else N.push({to:O.domain,path:D,static:{dir:`${d}/${R}-${t}/current`,spa:O.spa??!1,pathRewriteStyle:O.pathRewriteStyle??"directory"},cleanUrls:O.pathRewriteStyle!=="flat",...w?{auth:w}:{},id:C});A.add(O.domain)}if(T.proxy.autoWww!==!1)for(let t of[...A]){if(t.split(".").length!==2)continue;let O=`www.${t}`;if(A.has(O))continue;N.push({to:O,redirect:{to:`https://${t}`},id:DX(O)}),A.add(O)}N.sort((t,O)=>{if(t.to!==O.to)return t.to.localeCompare(O.to);return(O.path?.length??0)-(t.path?.length??0)});let S={proxies:N,productionCerts:{certsDir:h},https:!0,hostsManagement:!1,cleanup:{hosts:!1,certs:!1}};if(T.proxy.onDemandTls&&A.size>0)S.onDemandTls={enabled:!0,allowedSuffixes:[...A],email:T.proxy.onDemandTlsEmail,certsDir:h,staging:T.proxy.onDemandTlsStaging??!1};if(T.proxy.onDemandTls)S.acmeChallengeWebroot=T.proxy.acmeWebroot??u3;let L=T.proxy.cdn;if(L?.secret&&L.frontedHosts.length>0)S.originGuard={header:L.secretHeader??"X-Origin-Verify",value:L.secret,hosts:L.frontedHosts};return S}function Pr(E,T){return Vy(E,T)}function cS(E,T,_){return Vy(E,_,T)}function Nd(E){return E?.webServer==="rpx"||E?.proxy?.engine==="rpx"}function i3(E=wS,T=CX){return`// Generated by ts-cloud — rpx gateway assembler.
8389
+ `))}}async reveal(E){let T=this.store.get(E.entryId);if(!T||T.kind!=="secret")throw Error("Configuration secret was not found.");if(!E.canRevealSecrets)throw Error("Secret reveal permission is required.");if(!E.recentlyAuthenticated)throw Error("Recent authentication is required to reveal a secret.");let _=await this.backend(T.backend).resolve(T.secretRef);return this.audit(T.projectId,E.actorId,"configuration.secret.revealed",T,[]),_}async remove(E){let T=this.store.get(E.entryId);if(!T)throw Error("Configuration entry was not found.");let _=this.store.dependencies(T.id);if(((T.scope.environmentId?this.store.controlPlane.listEnvironments(T.projectId).some((r)=>r.id===T.scope.environmentId&&r.kind==="production"):T.scope.type==="project")||_.length)&&!E.confirmed)throw Error("Confirmation is required because this configuration affects production or dependent services.");if(T.kind==="secret"&&T.backend!=="external")await this.backend(T.backend).remove(T.secretRef);this.store.remove(T.id,E.expectedVersion);let R=hd(_.map((r)=>r.resourceId)),h={added:[],changed:[],removed:[T.key],unchanged:[],affectedResourceIds:R,versions:{}};return this.audit(T.projectId,E.actorId,"configuration.deleted",T,R),h}applies(E,T){if(E.scope.type==="project")return!0;if(E.scope.type==="environment")return E.scope.id===T.environmentId;if(E.scope.type==="service")return E.scope.id===T.resourceId;if(E.scope.type==="function")return E.scope.id===T.functionId;return E.scope.id===T.previewId}rank(E){return{project:0,environment:1,service:2,function:3,preview:4}[E]}fingerprint(E){return`hmac-sha256:${_q("sha256",this.fingerprintKey).update(E).digest("hex")}`}requestHash(E){return this.fingerprint(JSON.stringify({...E,idempotencyKey:void 0,actorId:void 0}))}backend(E){let T=this.backends.get(E);if(!T)throw Error(`Configuration secret backend is not configured: ${E}`);return T}backendName(E){return`ts-cloud/${E.projectId}/${E.scope.type}/${E.scope.id}/${E.key}`.replace(/[^A-Za-z0-9/_+=.@-]/g,"-")}isProduction(E){return E.scope.type==="project"||!!E.scope.environmentId&&this.store.controlPlane.listEnvironments(E.projectId).some((T)=>T.id===E.scope.environmentId&&T.kind==="production")}warnings(E,T){let _=[];if(Rq.test(E))_.push({key:E,code:"reserved",message:`${E} may be reserved by the runtime or provider.`});if(Buffer.byteLength(T)>65536)_.push({key:E,code:"limit",message:`${E} exceeds the portable 64 KiB value limit.`});return _}affectedResources(E,T,_){let d=this.store.list({projectId:E,scope:T}).filter((R)=>_.includes(R.key)).flatMap((R)=>this.store.dependencies(R.id).map((h)=>h.resourceId));if(T.type==="service"||T.type==="function")return hd([...d,T.id]);if(T.type==="environment")return hd([...d,...this.store.controlPlane.listResources(E,T.id).map((R)=>R.id)]);if(T.type==="preview"){let R=this.store.controlPlane.database.query("SELECT resource_id FROM preview_instances WHERE id=?").get(T.id);return hd([...d,...R?[R.resource_id]:[]])}return hd([...d,...this.store.controlPlane.listResources(E).map((R)=>R.id)])}audit(E,T,_,d,R){this.store.controlPlane.appendEvent({projectId:E,actorId:T,type:_,payload:{entryId:d.id,key:d.key,kind:d.kind,scopeType:d.scope.type,scopeId:d.scope.id,backend:d.backend,version:d.version,affectedResourceIds:R}})}}var dq,Rq;var CH=cE(async()=>{Qw();Gw();await d_();dq=/^(?:secret|aws-sm|aws-ssm|vault|doppler|op|external):\/\//,Rq=/^(?:AWS_|TS_CLOUD_|PORT$|HOST$)/});async function Dt(E,T,_,d){let R={added:0,changed:0,removed:0,overridden:0},h=async(r,N)=>{let A=E.store.list({projectId:T.project.id,scope:r,kind:"variable"}),S=new Set(Object.keys(N));for(let L of A.filter((t)=>t.origin==="config"&&!S.has(t.key)))await E.remove({entryId:L.id,expectedVersion:L.version,confirmed:!0,actorId:d}),R.removed++;for(let[L,t]of Object.entries(N)){let O=E.store.find(T.project.id,r,L);if(O?.origin!=="config"){if(O)R.overridden++;else await E.set({organizationId:T.organization.id,projectId:T.project.id,scope:r,key:L,kind:"variable",value:String(t),origin:"config",confirmed:!0,actorId:d}),R.added++;continue}if(O.value===String(t))continue;await E.set({organizationId:T.organization.id,projectId:T.project.id,scope:r,key:L,kind:"variable",value:String(t),origin:"config",confirmed:!0,actorId:d,expectedVersion:O.version}),R.changed++}};for(let[r,N]of Object.entries(_.environments??{})){let A=T.environments.get(r);if(!A)continue;let S=N,L={...S.variables??{},...S.app?.env??{}};await h({type:"environment",id:A.id,environmentId:A.id},L);for(let[t,O]of Object.entries(_.sites??{})){let U=T.store.listResources(T.project.id,A.id).find((D)=>D.kind==="application"&&D.slug===t);if(U)await h({type:"service",id:U.id,environmentId:A.id,resourceId:U.id},{...O.env??{}})}for(let[t,O]of Object.entries(_.infrastructure?.functions??{})){let U=T.store.listResources(T.project.id,A.id).find((D)=>D.kind==="function"&&D.slug===t);if(U)await h({type:"function",id:U.id,environmentId:A.id,resourceId:U.id},{...O.environment??{}})}}return R}var wH={};KT(wH,{synchronizeConfiguredConfiguration:()=>Dt,serializeDotenv:()=>ew,parseDotenv:()=>Yw,LocalEncryptedConfigurationBackend:()=>zr,ExternalConfigurationBackend:()=>gA,ConfigurationStore:()=>ZA,ConfigurationService:()=>vA,AwsSsmConfigurationBackend:()=>xA,AwsSecretsManagerConfigurationBackend:()=>qA});var It=cE(async()=>{Gw();Qw();CH()});function $y(E,T=""){return E===408||E===409||E===425||E===429||E>=500||/rate limit|temporar|timed? ?out|try again/i.test(T)}async function ac(E,T){let _=T?.headers.get("retry-after"),d=_===null||_===void 0?void 0:Number(_)*1000,R=Number.isFinite(d)?Math.max(0,d):Math.min(1000*2**(E-1),30000);await new Promise((h)=>setTimeout(h,R))}var eN;var sc=cE(()=>{eN=class eN{name="porkbun";apiKey;secretKey;requestTimeoutMs;constructor(E,T,_=15000){this.apiKey=E,this.secretKey=T,this.requestTimeoutMs=_}async request(E,T={}){let _;for(let d=1;d<=8;d+=1){let R,h=new AbortController,r=setTimeout(()=>{h.abort(Error(`Porkbun API request timed out after ${this.requestTimeoutMs}ms`))},this.requestTimeoutMs);try{R=await fetch(`https://api.porkbun.com/api/json/v3${E}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...T}),signal:h.signal})}catch(A){if(_=A,d===8)throw A;await ac(d);continue}finally{clearTimeout(r)}if(!R.ok){if(_=Error(`Porkbun API error: ${R.status} ${R.statusText}`),!$y(R.status)||d===8)throw _;await ac(d,R);continue}let N=await R.json();if(N.status==="ERROR"){if(_=Error(`Porkbun API error: ${N.message||"Unknown error"}`),!$y(0,N.message)||d===8)throw _;await ac(d,R);continue}return N}throw _}getSubdomain(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(_===d)return"";if(_.endsWith(`.${d}`))return _.slice(0,-(d.length+1));return _}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}static ADDRESS_TYPES=new Set(["A","AAAA"]);async clearConflictingAliases(E,T){if(!eN.ADDRESS_TYPES.has(T.type))return[];let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return[`could not list records to clear ALIAS/CNAME conflicts: ${R.message??"unknown provider error"}`];let h=[];for(let r of R.records){if(r.type!=="ALIAS"&&r.type!=="CNAME")continue;if(this.getSubdomain(r.name,_)!==d)continue;let N=await this.deleteRecord(E,r);if(!N.success)h.push(`could not remove conflicting ${r.type} on ${r.name}: ${N.message??"unknown provider error"}`)}return h}async addressRecordExists(E,T){let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return!0;return R.records.some((h)=>h.type===T.type&&this.getSubdomain(h.name,_)===d&&h.content===T.content)}async createRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R={type:T.type,content:T.content,ttl:String(T.ttl||600)};if(d)R.name=d;if((T.type==="MX"||T.type==="SRV")&&T.priority!==void 0)R.prio=String(T.priority);if(T.type==="SRV"&&T.weight!==void 0&&T.port!==void 0)R.content=`${T.weight} ${T.port} ${T.content}`;let h=await this.clearConflictingAliases(E,T),r=await this.request(`/dns/create/${_}`,R);if(eN.ADDRESS_TYPES.has(T.type)&&!await this.addressRecordExists(E,T))return{success:!1,message:`Porkbun reported success but no ${T.type} record for ${T.name} exists${h.length>0?` (${h.join("; ")})`:""}. A conflicting ALIAS/CNAME on the same name silently voids the write.`};return{success:!0,id:r.id?.toString(),message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.listRecords(E,T.type);if(R.success){let h=R.records.find((r)=>{return this.getSubdomain(r.name,_)===d&&r.type===T.type});if(h?.id){let r={type:T.type,content:T.content,ttl:String(T.ttl||600)};if(d)r.name=d;if((T.type==="MX"||T.type==="SRV")&&T.priority!==void 0)r.prio=String(T.priority);if(T.type==="SRV"&&T.weight!==void 0&&T.port!==void 0)r.content=`${T.weight} ${T.port} ${T.content}`;return await this.request(`/dns/edit/${_}/${h.id}`,r),{success:!0,id:h.id,message:"Record updated successfully"}}}return this.createRecord(E,T)}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=this.getRootDomain(E);if("id"in T&&T.id)return await this.request(`/dns/delete/${_}/${T.id}`),{success:!0,message:"Record deleted successfully"};let d=this.getSubdomain(T.name,_),R=await this.listRecords(E);if(!R.success)return{success:!1,message:"Failed to list records"};let h=R.records.find((r)=>{return this.getSubdomain(r.name,_)===d&&r.type===T.type&&r.content===T.content});if(!h?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${_}/${h.id}`),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=this.getRootDomain(E),d=`/dns/retrieve/${_}`;if(T)d=`/dns/retrieveByNameType/${_}/${T}`;return{success:!0,records:((await this.request(d)).records||[]).map((r)=>({id:r.id,name:r.name||_,type:r.type,content:r.content,ttl:Number.parseInt(r.ttl,10),priority:r.prio?Number.parseInt(r.prio,10):void 0}))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{let T=this.getRootDomain(E);return await this.request(`/dns/retrieve/${T}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((T)=>T.domain)}catch{return[]}}async getNameServers(E){try{let T=this.getRootDomain(E);return(await this.request(`/dns/getNS/${T}`)).ns||[]}catch{return[]}}async updateNameServers(E,T){try{let _=this.getRootDomain(E);return await this.request(`/dns/updateNS/${_}`,{ns:T}),!0}catch{return!1}}}});class Yt{name="godaddy";apiKey;apiSecret;baseUrl;constructor(E,T,_="production"){this.apiKey=E,this.apiSecret=T,this.baseUrl=_==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request(E,T,_){let d=`${this.baseUrl}${T}`,R={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},h={method:E,headers:R};if(_)h.body=JSON.stringify(_);let r=await fetch(d,h);if(r.status===204)return{};if(r.ok){let A=await r.text();if(A)return JSON.parse(A);return{}}let N=`GoDaddy API error: ${r.status} ${r.statusText}`;try{let A=await r.json();if(A.message)N=`GoDaddy API error: ${A.message}`;if(A.fields)N+=` - Fields: ${JSON.stringify(A.fields)}`}catch{}throw Error(N)}getSubdomain(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(_===d)return"@";if(_.endsWith(`.${d}`))return _.slice(0,-(d.length+1));return _}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}toGoDaddyRecord(E,T){let _=this.getRootDomain(T),d=this.getSubdomain(E.name,_),R={type:E.type,name:d,data:E.content,ttl:E.ttl||600};if(E.type==="MX"&&E.priority!==void 0)R.priority=E.priority;return R}fromGoDaddyRecord(E,T){let _=this.getRootDomain(T),d=E.name;if(d==="@")d=_;else if(!d.endsWith(_))d=`${d}.${_}`;return{name:d,type:E.type,content:E.data,ttl:E.ttl,priority:E.priority}}async createRecord(E,T){try{let _=this.getRootDomain(E),d=this.toGoDaddyRecord(T,E);return await this.request("PATCH",`/v1/domains/${_}/records`,[d]),{success:!0,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=this.getRootDomain(E),d=this.toGoDaddyRecord(T,E);return await this.request("PUT",`/v1/domains/${_}/records/${T.type}/${d.name}`,[d]),{success:!0,message:"Record upserted successfully"}}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=this.getRootDomain(E),d=this.getSubdomain(T.name,_),R=await this.request("GET",`/v1/domains/${_}/records/${T.type}/${d}`),h=R.filter((r)=>r.data!==T.content);if(h.length===R.length)return{success:!1,message:"Record not found"};if(h.length===0)try{await this.request("DELETE",`/v1/domains/${_}/records/${T.type}/${d}`)}catch{}else await this.request("PUT",`/v1/domains/${_}/records/${T.type}/${d}`,h);return{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=this.getRootDomain(E),d=`/v1/domains/${_}/records`;if(T)d=`/v1/domains/${_}/records/${T}`;return{success:!0,records:(await this.request("GET",d)).map((h)=>this.fromGoDaddyRecord(h,E))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{let T=this.getRootDomain(E);return await this.request("GET",`/v1/domains/${T}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((T)=>T.domain)}catch{return[]}}async getDomainDetails(E){try{let T=this.getRootDomain(E),_=await this.request("GET",`/v1/domains/${T}`);return{domain:_.domain,status:_.status,nameServers:_.nameServers,expires:_.expires}}catch{return null}}async updateNameServers(E,T){try{let _=this.getRootDomain(E);return await this.request("PUT",`/v1/domains/${_}/records/NS`,T.map((d)=>({type:"NS",name:"@",data:d,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability(E){try{let T=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent(E)}`);return{available:T.available,price:T.price,currency:T.currency}}catch{return{available:!1}}}}class X${name="cloudflare";apiToken;zoneCache=new Map;constructor(E){this.apiToken=E}async request(E,T,_){let d=`https://api.cloudflare.com/client/v4${T}`,R={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},h={method:E,headers:R};if(_)h.body=JSON.stringify(_);let N=await(await fetch(d,h)).json();if(!N.success){let A=N.errors.map((S)=>S.message).join(", ");throw Error(`Cloudflare API error: ${A}`)}return N}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}async getZoneId(E){let T=this.getRootDomain(E),_=this.zoneCache.get(T);if(_)return _;let d=await this.request("GET",`/zones?name=${encodeURIComponent(T)}`);if(!d.result||d.result.length===0)throw Error(`Zone not found for domain: ${T}`);let R=d.result[0].id;return this.zoneCache.set(T,R),R}getFullRecordName(E,T){let _=this.getRootDomain(T),d=E.replace(/\.$/,"");if(!d||d===_||d==="@")return _;if(d.endsWith(`.${_}`))return d;return`${d}.${_}`}toCloudflareRecord(E,T){let _={type:E.type,name:this.getFullRecordName(E.name,T),content:E.content||E.value||"",ttl:E.ttl||1};if(E.type==="MX"&&E.priority!==void 0)_.priority=E.priority;if(E.type==="SRV"){if(E.priority!==void 0)_.priority=E.priority}return _}fromCloudflareRecord(E){return{id:E.id,name:E.name,type:E.type,content:E.content,ttl:E.ttl,priority:E.priority}}async createRecord(E,T){try{let _=await this.getZoneId(E),d=this.toCloudflareRecord(T,E);return{success:!0,id:(await this.request("POST",`/zones/${_}/dns_records`,d)).result.id,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`),h=this.toCloudflareRecord(T,E);if(R.result&&R.result.length>0){let N=R.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${_}/dns_records/${N}`,h)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${_}/dns_records`,h)).result.id,message:"Record created successfully"}}catch(_){return this.createRecord(E,T)}}async deleteRecord(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`);if(!R.result||R.result.length===0)return{success:!1,message:"Record not found"};let h=R.result.find((r)=>r.content===T.content);if(!h)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${_}/dns_records/${h.id}`),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let d=`/zones/${await this.getZoneId(E)}/dns_records?per_page=100`;if(T)d+=`&type=${T}`;let R=[],h=1,r=!0;while(r){let N=await this.request("GET",`${d}&page=${h}`);if(R.push(...N.result||[]),N.result_info)r=h<N.result_info.total_pages,h++;else r=!1}return{success:!0,records:R.map((N)=>this.fromCloudflareRecord(N))}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){try{return await this.getZoneId(E),!0}catch{return!1}}async listDomains(){try{let E=[],T=1,_=!0;while(_){let d=await this.request("GET",`/zones?per_page=50&page=${T}`);if(E.push(...d.result||[]),d.result_info)_=T<d.result_info.total_pages,T++;else _=!1}return E.map((d)=>d.name)}catch{return[]}}async getZoneDetails(E){try{let T=await this.getZoneId(E),_=await this.request("GET",`/zones/${T}`);return{id:_.result.id,name:_.result.name,status:_.result.status,nameServers:_.result.name_servers,paused:_.result.paused}}catch{return null}}async purgeCache(E,T){try{let _=await this.getZoneId(E),d={};if(T?.purgeEverything)d.purge_everything=!0;else{if(T?.files)d.files=T.files;if(T?.tags)d.tags=T.tags;if(T?.hosts)d.hosts=T.hosts}if(Object.keys(d).length===0)d.purge_everything=!0;return await this.request("POST",`/zones/${_}/purge_cache`,d),!0}catch{return!1}}async getRecordProxyStatus(E,T){try{let _=await this.getZoneId(E),d=this.getFullRecordName(T.name,E),R=await this.request("GET",`/zones/${_}/dns_records?type=${T.type}&name=${encodeURIComponent(d)}`);if(R.result&&R.result.length>0)return R.result.find((r)=>r.content===T.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus(E,T,_){try{let d=await this.getZoneId(E),R=this.getFullRecordName(T.name,E),h=await this.request("GET",`/zones/${d}/dns_records?type=${T.type}&name=${encodeURIComponent(R)}`);if(!h.result||h.result.length===0)return!1;let r=h.result.find((N)=>N.content===T.content);if(!r)return!1;return await this.request("PATCH",`/zones/${d}/dns_records/${r.id}`,{proxied:_}),!0}catch{return!1}}}class GN{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor(E="us-east-1",T){this.client=new $_(E),this.providedHostedZoneId=T}getRootDomain(E){let T=E.replace(/\.$/,"").split(".");if(T.length>=2)return T.slice(-2).join(".");return E}async getHostedZoneId(E){if(this.providedHostedZoneId)return this.providedHostedZoneId;let T=this.getRootDomain(E),_=this.hostedZoneCache.get(T);if(_)return _;let d=await this.client.findHostedZoneForDomain(E);if(d){let R=d.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(T,R),R}return null}normalizeName(E,T){let _=E.replace(/\.$/,""),d=T.replace(/\.$/,"");if(!d||d==="@")return`${_}.`;if(d===_||d.endsWith(`.${_}`))return`${d}.`;return`${d}.${_}.`}async createRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async upsertRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async deleteRecord(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,message:`No hosted zone found for domain: ${E}`};let d=this.normalizeName(E,T.name),R=T.content;if(T.type==="TXT"&&!R.startsWith('"'))R=`"${R}"`;if(T.type==="MX"&&T.priority!==void 0)R=`${T.priority} ${R}`;return await this.client.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:d,Type:T.type,TTL:T.ttl||300,ResourceRecords:[{Value:R}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(_){return{success:!1,message:_ instanceof Error?_.message:"Unknown error"}}}async listRecords(E,T){try{let _=await this.getHostedZoneId(E);if(!_)return{success:!1,records:[],message:`No hosted zone found for domain: ${E}`};let d=await this.client.listResourceRecordSets({HostedZoneId:_,StartRecordType:T}),R=[];for(let h of d.ResourceRecordSets){if(T&&h.Type!==T)continue;if(h.AliasTarget)continue;for(let r of h.ResourceRecords||[]){let N=r.Value,A;if(h.Type==="MX"){let S=N.split(" ");if(S.length>=2)A=Number.parseInt(S[0],10),N=S.slice(1).join(" ")}if(h.Type==="TXT"&&N.startsWith('"')&&N.endsWith('"'))N=N.slice(1,-1);R.push({name:h.Name.replace(/\.$/,""),type:h.Type,content:N,ttl:h.TTL,priority:A})}}return{success:!0,records:R}}catch(_){return{success:!1,records:[],message:_ instanceof Error?_.message:"Unknown error"}}}async canManageDomain(E){return await this.getHostedZoneId(E)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((T)=>T.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord(E){try{let T=await this.getHostedZoneId(E.domain);if(!T)return{success:!1,message:`No hosted zone found for domain: ${E.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:T,Name:this.normalizeName(E.domain,E.name),TargetHostedZoneId:E.targetHostedZoneId,TargetDNSName:E.targetDnsName,EvaluateTargetHealth:E.evaluateTargetHealth,Type:E.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(T){return{success:!1,message:T instanceof Error?T.message:"Unknown error"}}}async createCloudFrontAlias(E){return this.createAliasRecord({domain:E.domain,name:E.name,targetHostedZoneId:$_.CloudFrontHostedZoneId,targetDnsName:E.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias(E){let T=$_.ALBHostedZoneIds[E.region];if(!T)return{success:!1,message:`Unknown region for ALB: ${E.region}`};return this.createAliasRecord({domain:E.domain,name:E.name,targetHostedZoneId:T,targetDnsName:E.albDnsName,evaluateTargetHealth:!0})}}var J$=cE(()=>{UN()});var Dy={};KT(Dy,{ACMDnsValidator:()=>et,ACMClient:()=>X_});class X_{client;region;constructor(E="us-east-1"){this.client=new zE,this.region=E}async requestCertificate(E){let T={DomainName:E.DomainName,ValidationMethod:E.ValidationMethod||"DNS"};if(E.SubjectAlternativeNames)T.SubjectAlternativeNames=E.SubjectAlternativeNames;return{CertificateArn:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.RequestCertificate"},body:JSON.stringify(T)})).CertificateArn||""}}async describeCertificate(E){let _=(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DescribeCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})).Certificate||{};return{CertificateArn:_.CertificateArn||"",DomainName:_.DomainName||"",SubjectAlternativeNames:_.SubjectAlternativeNames,Status:_.Status||"PENDING_VALIDATION",Type:_.Type,DomainValidationOptions:_.DomainValidationOptions?.map((d)=>({DomainName:d.DomainName,ValidationDomain:d.ValidationDomain,ValidationStatus:d.ValidationStatus,ResourceRecord:d.ResourceRecord?{Name:d.ResourceRecord.Name,Type:d.ResourceRecord.Type,Value:d.ResourceRecord.Value}:void 0,ValidationMethod:d.ValidationMethod})),CreatedAt:_.CreatedAt,IssuedAt:_.IssuedAt,NotBefore:_.NotBefore,NotAfter:_.NotAfter}}async listCertificates(E){let T={};if(E?.CertificateStatuses)T.CertificateStatuses=E.CertificateStatuses;if(E?.MaxItems)T.MaxItems=E.MaxItems;if(E?.NextToken)T.NextToken=E.NextToken;let _=await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListCertificates"},body:JSON.stringify(T)});return{CertificateSummaryList:(_.CertificateSummaryList||[]).map((d)=>({CertificateArn:d.CertificateArn,DomainName:d.DomainName})),NextToken:_.NextToken}}async deleteCertificate(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DeleteCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})}async listTagsForCertificate(E){return{Tags:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListTagsForCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn})})).Tags||[]}}async addTagsToCertificate(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.AddTagsToCertificate"},body:JSON.stringify({CertificateArn:E.CertificateArn,Tags:E.Tags})})}async resendValidationEmail(E){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ResendValidationEmail"},body:JSON.stringify({CertificateArn:E.CertificateArn,Domain:E.Domain,ValidationDomain:E.ValidationDomain})})}async findCertificateByDomain(E){let _=(await this.listCertificates({CertificateStatuses:["ISSUED"]})).CertificateSummaryList.find((d)=>d.DomainName===E||d.DomainName===`*.${E.split(".").slice(1).join(".")}`);if(!_)return null;return this.describeCertificate({CertificateArn:_.CertificateArn})}async waitForCertificateValidation(E,T=60,_=30000){for(let d=0;d<T;d++){let R=await this.describeCertificate({CertificateArn:E});if(R.Status==="ISSUED")return R;if(R.Status==="FAILED"||R.Status==="VALIDATION_TIMED_OUT")return null;await new Promise((h)=>setTimeout(h,_))}return null}async getDnsValidationRecords(E){let T=await this.describeCertificate({CertificateArn:E});if(!T.DomainValidationOptions)return[];return T.DomainValidationOptions.filter((_)=>_.ResourceRecord&&_.ValidationMethod==="DNS").map((_)=>({domainName:_.DomainName,recordName:_.ResourceRecord.Name,recordType:_.ResourceRecord.Type,recordValue:_.ResourceRecord.Value}))}async requestCertificateWithSans(E){let T=new Set;if(T.add(E.DomainName),E.IncludeWww!==!1)T.add(`www.${E.DomainName}`);if(E.IncludeWildcard)T.add(`*.${E.DomainName}`);if(E.AdditionalSans)for(let _ of E.AdditionalSans)T.add(_);return this.requestCertificate({DomainName:E.DomainName,SubjectAlternativeNames:Array.from(T),ValidationMethod:"DNS"})}async isCertificateValidForDomain(E,T){let _=await this.describeCertificate({CertificateArn:E});if(_.Status!=="ISSUED")return!1;if(_.DomainName===T)return!0;if(_.DomainName?.startsWith("*.")){let d=_.DomainName.slice(2),R=T.split("."),h=d.split(".");if(R.slice(-h.length).join(".")===d)return!0}if(_.SubjectAlternativeNames)for(let d of _.SubjectAlternativeNames){if(d===T)return!0;if(d.startsWith("*.")){let R=d.slice(2),h=T.split("."),r=R.split(".");if(h.slice(-r.length).join(".")===R)return!0}}return!1}}class et{acm;route53;dnsProvider;constructor(E="us-east-1",T){if(this.acm=new X_(E),this.route53=new $_,T&&T.provider!=="route53")this.dnsProvider=Y_(T)}async requestAndValidate(E){let{domainName:T,hostedZoneId:_,subjectAlternativeNames:d=[],waitForValidation:R=!1,maxWaitMinutes:h=30}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let{CertificateArn:r}=await this.acm.requestCertificate({DomainName:T,SubjectAlternativeNames:d.length>0?[T,...d]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(r);let N=await this.acm.getDnsValidationRecords(r);if(this.dnsProvider)for(let A of N){let S=await this.dnsProvider.upsertRecord(T,{name:A.recordName,type:A.recordType,content:A.recordValue,ttl:300});if(!S.success)console.warn(`Failed to create validation record for ${A.domainName}: ${S.message}`)}else if(_)for(let A of N)await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`ACM DNS validation for ${A.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:A.recordName,Type:A.recordType,TTL:300,ResourceRecords:[{Value:A.recordValue}]}}]}});if(R){if(!await this.acm.waitForCertificateValidation(r,h*2,30000))throw Error(`Certificate validation timed out after ${h} minutes`)}return{certificateArn:r,validationRecords:N}}async waitForValidationOptions(E,T=30){for(let _=0;_<T;_++){let d=await this.acm.describeCertificate({CertificateArn:E});if(d.DomainValidationOptions&&d.DomainValidationOptions.length>0&&d.DomainValidationOptions[0].ResourceRecord)return;await new Promise((R)=>setTimeout(R,2000))}throw Error("Timeout waiting for DNS validation options")}async createValidationRecords(E){let{certificateArn:T,hostedZoneId:_,domain:d}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let R=await this.acm.getDnsValidationRecords(T),h=[];if(this.dnsProvider){let r=d||R[0]?.domainName;for(let N of R){let A=await this.dnsProvider.upsertRecord(r,{name:N.recordName,type:N.recordType,content:N.recordValue,ttl:300});h.push({...N,changeId:A.success?A.id:void 0})}}else if(_)for(let r of R){let N=await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`ACM DNS validation for ${r.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:r.recordName,Type:r.recordType,TTL:300,ResourceRecords:[{Value:r.recordValue}]}}]}});h.push({...r,changeId:N.ChangeInfo?.Id})}return h}async deleteValidationRecords(E){let{certificateArn:T,hostedZoneId:_,domain:d}=E,R=await this.acm.getDnsValidationRecords(T);if(this.dnsProvider){let h=d||R[0]?.domainName;for(let r of R)try{await this.dnsProvider.deleteRecord(h,{name:r.recordName,type:r.recordType,content:r.recordValue})}catch{}}else if(_)for(let h of R)try{await this.route53.changeResourceRecordSets({HostedZoneId:_,ChangeBatch:{Comment:`Cleanup ACM DNS validation for ${h.domainName}`,Changes:[{Action:"DELETE",ResourceRecordSet:{Name:h.recordName,Type:h.recordType,TTL:300,ResourceRecords:[{Value:h.recordValue}]}}]}})}catch{}}async findOrCreateCertificate(E){let{domainName:T,hostedZoneId:_,subjectAlternativeNames:d,waitForValidation:R=!0}=E;if(!this.dnsProvider&&!_)throw Error("Either hostedZoneId or external DNS provider configuration is required");let h=await this.acm.findCertificateByDomain(T);if(h&&h.Status==="ISSUED")return{certificateArn:h.CertificateArn,isNew:!1};let{certificateArn:r}=await this.requestAndValidate({domainName:T,hostedZoneId:_,subjectAlternativeNames:d,waitForValidation:R});return{certificateArn:r,isNew:!0}}hasExternalDnsProvider(){return this.dnsProvider!==void 0}getDnsProviderName(){return this.dnsProvider?.name||"route53"}}var Bh=cE(()=>{VE();UN();gR()});class QN{acm;dnsProvider;constructor(E,T="us-east-1"){if(this.acm=new X_(T),"provider"in E)this.dnsProvider=Y_(E);else this.dnsProvider=E}getProvider(){return this.dnsProvider}async requestAndValidate(E){let{domainName:T,subjectAlternativeNames:_=[],waitForValidation:d=!1,maxWaitMinutes:R=30}=E,{CertificateArn:h}=await this.acm.requestCertificate({DomainName:T,SubjectAlternativeNames:_.length>0?[T,..._]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(h);let r=await this.acm.getDnsValidationRecords(h);for(let A of r){let S=await this.dnsProvider.upsertRecord(T,{name:A.recordName,type:A.recordType,content:A.recordValue,ttl:300});if(!S.success)console.warn(`Failed to create validation record for ${A.domainName}: ${S.message}`)}let N="pending";if(d)N=(await this.acm.waitForCertificateValidation(h,R*2,30000))?.Status==="ISSUED"?"issued":"failed";return{certificateArn:h,validationRecords:r.map((A)=>({domainName:A.domainName,recordName:A.recordName,recordType:A.recordType,recordValue:A.recordValue})),isNew:!0,status:N}}async createValidationRecords(E){let{certificateArn:T,domain:_}=E,d=[],R=await this.acm.getDnsValidationRecords(T);for(let h of R){let r=await this.dnsProvider.upsertRecord(_,{name:h.recordName,type:h.recordType,content:h.recordValue,ttl:300});if(!r.success)d.push(`Failed to create record for ${h.domainName}: ${r.message}`)}return{success:d.length===0,records:R.map((h)=>({domainName:h.domainName,recordName:h.recordName,recordType:h.recordType,recordValue:h.recordValue})),errors:d}}async deleteValidationRecords(E){let{certificateArn:T,domain:_}=E,d=[],R=await this.acm.getDnsValidationRecords(T);for(let h of R){let r=await this.dnsProvider.deleteRecord(_,{name:h.recordName,type:h.recordType,content:h.recordValue});if(!r.success)d.push(`Failed to delete record for ${h.domainName}: ${r.message}`)}return{success:d.length===0,errors:d}}async findOrCreateCertificate(E){let{domainName:T,subjectAlternativeNames:_=[],waitForValidation:d=!0,maxWaitMinutes:R}=E,h=await this.acm.findCertificateByDomain(T);if(h&&h.Status==="ISSUED"){let r=h.SubjectAlternativeNames||[h.DomainName],N=r.some((S)=>S===`*.${T}`);if(_.every((S)=>r.includes(S)||N))return{certificateArn:h.CertificateArn,validationRecords:[],isNew:!1,status:"issued"};console.log("Existing certificate doesn't cover all required SANs, requesting new certificate...")}return this.requestAndValidate({domainName:T,subjectAlternativeNames:_,waitForValidation:d,maxWaitMinutes:R})}async requestCertificateWithCommonSans(E){let{domainName:T,includeWww:_=!0,includeWildcard:d=!1,additionalSans:R=[],waitForValidation:h=!1}=E,r=[];if(_)r.push(`www.${T}`);if(d)r.push(`*.${T}`);return r.push(...R),this.requestAndValidate({domainName:T,subjectAlternativeNames:r,waitForValidation:h})}async waitForValidationOptions(E,T=30){for(let _=0;_<T;_++){let d=await this.acm.describeCertificate({CertificateArn:E});if(d.DomainValidationOptions&&d.DomainValidationOptions.length>0&&d.DomainValidationOptions[0].ResourceRecord)return;await new Promise((R)=>setTimeout(R,2000))}throw Error("Timeout waiting for DNS validation options")}async getCertificateStatus(E){let T=await this.acm.describeCertificate({CertificateArn:E});return{status:T.Status,domainValidations:(T.DomainValidationOptions||[]).map((_)=>({domain:_.DomainName,status:_.ValidationStatus||"UNKNOWN"}))}}}var pc=cE(()=>{Bh();gR()});function Y_(E){switch(E.provider){case"route53":return new GN(E.region,E.hostedZoneId);case"porkbun":return new eN(E.apiKey,E.secretKey);case"godaddy":return new Yt(E.apiKey,E.apiSecret,E.environment);case"cloudflare":return new X$(E.apiToken);default:throw Error(`Unknown DNS provider: ${E.provider}`)}}class Gt{providers=new Map;configs=[];addConfig(E){return this.configs.push(E),this}addRoute53(E,T){return this.configs.push({provider:"route53",region:E,hostedZoneId:T}),this}addPorkbun(E,T){return this.configs.push({provider:"porkbun",apiKey:E,secretKey:T}),this}addGoDaddy(E,T,_){return this.configs.push({provider:"godaddy",apiKey:E,apiSecret:T,environment:_}),this}addCloudflare(E){return this.configs.push({provider:"cloudflare",apiToken:E}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let E=process.env.PORKBUN_API_KEY,T=process.env.PORKBUN_SECRET_KEY;if(E&&T)this.addPorkbun(E,T);let _=process.env.GODADDY_API_KEY,d=process.env.GODADDY_API_SECRET;if(_&&d){let h=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(_,d,h)}let R=process.env.CLOUDFLARE_API_TOKEN;if(R)this.addCloudflare(R);return this}getProvider(E){let T=this.providers.get(E);if(T)return T;let _=this.configs.find((R)=>R.provider===E);if(!_)return null;let d=Y_(_);return this.providers.set(E,d),d}async getProviderForDomain(E){for(let T of this.configs){let _=Y_(T);if(await _.canManageDomain(E))return _}return null}getAllProviders(){return this.configs.map((E)=>Y_(E))}}var L3;var gR=cE(()=>{sc();J$();pc();sc();J$();L3=new Gt});var hX={};KT(hX,{CloudFormationClient:()=>oE});class oE{client;region;constructor(E="us-east-1",T){this.region=E,this.client=new zE(void 0,{profile:T})}async createStack(E){let T={Action:"CreateStack",StackName:E.stackName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(E.parameters)E.parameters.forEach((d,R)=>{T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.roleArn)T.RoleARN=E.roleArn;if(E.tags)E.tags.forEach((d,R)=>{T[`Tags.member.${R+1}.Key`]=d.Key,T[`Tags.member.${R+1}.Value`]=d.Value});if(E.timeoutInMinutes)T.TimeoutInMinutes=E.timeoutInMinutes;if(E.onFailure)T.OnFailure=E.onFailure;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackId:_.StackId||_.CreateStackResult?.StackId}}async updateStack(E){let T={Action:"UpdateStack",StackName:E.stackName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;if(E.parameters)E.parameters.forEach((d,R)=>{if(T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,d.UsePreviousValue)T[`Parameters.member.${R+1}.UsePreviousValue`]="true";else T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.roleArn)T.RoleARN=E.roleArn;if(E.tags)E.tags.forEach((d,R)=>{T[`Tags.member.${R+1}.Key`]=d.Key,T[`Tags.member.${R+1}.Value`]=d.Value});let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackId:_.StackId||_.UpdateStackResult?.StackId}}async deleteStack(E,T,_){let d={Action:"DeleteStack",StackName:E,Version:"2010-05-15"};if(T)d.RoleARN=T;if(_&&_.length>0)_.forEach((R,h)=>{d[`RetainResources.member.${h+1}`]=R});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(d).toString()})}async describeStacks(E={}){let T={Action:"DescribeStacks",Version:"2010-05-15"};if(E.stackName)T.StackName=E.stackName;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{Stacks:this.parseStacksResponse(_)}}async describeStackEvents(E){let T={Action:"DescribeStackEvents",StackName:E,Version:"2010-05-15"},_=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{StackEvents:this.parseStackEvents(_)}}async listStackResources(E){let T={Action:"ListStackResources",StackName:E,Version:"2010-05-15"},d=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,R=[];if(d)R=Array.isArray(d)?d:[d];return{StackResourceSummaries:R}}async waitForStack(E,T){let _={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},d=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],R=_[T],h=360,r=0;while(r<360)try{let N=await this.describeStacks({stackName:E});if(N.Stacks.length===0){if(T==="stack-delete-complete")return;if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Stack not visible yet`);await new Promise((S)=>setTimeout(S,2000)),r++;continue}let A=N.Stacks[0];if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Status = ${A.StackStatus}${A.StackStatusReason?` (${A.StackStatusReason})`:""}`);if(R.includes(A.StackStatus))return;if((T==="stack-create-complete"||T==="stack-update-complete")&&(A.StackStatus==="DELETE_IN_PROGRESS"||A.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let S="";try{let t=await this.describeStackEvents(E);console.log("[waitForStack] Stack events (most recent first):");for(let O of t.StackEvents.slice(0,15))if(O.ResourceStatus.includes("FAILED")||O.ResourceStatusReason){if(console.log(` ${O.LogicalResourceId}: ${O.ResourceStatus} - ${O.ResourceStatusReason||"No reason provided"}`),O.ResourceStatus.includes("FAILED")&&O.ResourceStatusReason&&!S)S=O.ResourceStatusReason}}catch{}let L=S||A.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${L}`)}if(A.StackStatus==="DELETE_FAILED"&&T==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=A.StackStatus,S.statusReason=A.StackStatusReason,S}if(d.includes(A.StackStatus))throw Error(`Stack reached failure status: ${A.StackStatus}`);await new Promise((S)=>setTimeout(S,5000)),r++}catch(N){if(T==="stack-delete-complete"&&N.message?.includes("does not exist"))return;if(T==="stack-create-complete"&&N.message?.includes("does not exist")){if(r%10===0)console.log(`[waitForStack] Attempt ${r}: Stack does not exist (error), retrying...`);await new Promise((A)=>setTimeout(A,2000)),r++;continue}throw console.log(`[waitForStack] Unexpected error: ${N.message}`),N}throw console.log(`[waitForStack] Timeout after ${r} attempts`),Error(`Timeout waiting for stack to reach ${T}`)}async validateTemplate(E){let T={Action:"ValidateTemplate",TemplateBody:E,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()})}async listStacks(E){let T={Action:"ListStacks",Version:"2010-05-15"};if(E)E.forEach((N,A)=>{T[`StackStatusFilter.member.${A+1}`]=N});let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()}),d=_.ListStacksResponse||_,R=d.ListStacksResult||d,h=R.StackSummaries?.member||R.StackSummaries||[];return{StackSummaries:(Array.isArray(h)?h:h?[h]:[]).map((N)=>({StackId:N.StackId||"",StackName:N.StackName||"",TemplateDescription:N.TemplateDescription,CreationTime:N.CreationTime||"",LastUpdatedTime:N.LastUpdatedTime,DeletionTime:N.DeletionTime,StackStatus:N.StackStatus||""}))}}async createChangeSet(E){let T={Action:"CreateChangeSet",StackName:E.stackName,ChangeSetName:E.changeSetName,Version:"2010-05-15"};if(E.templateBody)T.TemplateBody=E.templateBody;else if(E.templateUrl)T.TemplateURL=E.templateUrl;if(E.parameters)E.parameters.forEach((d,R)=>{T[`Parameters.member.${R+1}.ParameterKey`]=d.ParameterKey,T[`Parameters.member.${R+1}.ParameterValue`]=d.ParameterValue});if(E.capabilities)E.capabilities.forEach((d,R)=>{T[`Capabilities.member.${R+1}`]=d});if(E.changeSetType)T.ChangeSetType=E.changeSetType;let _=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{Id:_.Id,StackId:_.StackId}}async describeChangeSet(E,T){let _={Action:"DescribeChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async executeChangeSet(E,T){let _={Action:"ExecuteChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async deleteChangeSet(E,T){let _={Action:"DeleteChangeSet",StackName:E,ChangeSetName:T,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(_).toString()})}async getStackOutputs(E){let T=await this.describeStacks({stackName:E});if(!T.Stacks||T.Stacks.length===0)throw Error(`Stack ${E} not found`);let _=T.Stacks[0],d={};if(_.Outputs)for(let R of _.Outputs)d[R.OutputKey]=R.OutputValue;return d}async getTemplate(E){let T={Action:"GetTemplate",StackName:E,Version:"2010-05-15"},_=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(T).toString()});return{TemplateBody:_?.GetTemplateResult?.TemplateBody||_?.TemplateBody||""}}parseStacksResponse(E){let T=[],_=E?.DescribeStacksResult?.Stacks?.member||E?.Stacks?.member||E?.Stacks||E;if(_&&!Array.isArray(_))_=[_];if(Array.isArray(_)){for(let d of _)if(d.StackId||d.StackName){let R;if(d.Outputs?.member)R=(Array.isArray(d.Outputs.member)?d.Outputs.member:[d.Outputs.member]).map((r)=>({OutputKey:r.OutputKey,OutputValue:r.OutputValue,Description:r.Description,ExportName:r.ExportName}));T.push({StackId:d.StackId,StackName:d.StackName,StackStatus:d.StackStatus,CreationTime:d.CreationTime,LastUpdatedTime:d.LastUpdatedTime,StackStatusReason:d.StackStatusReason,Outputs:R})}}else if(E.StackId)T.push({StackId:E.StackId,StackName:E.StackName,StackStatus:E.StackStatus,CreationTime:E.CreationTime,LastUpdatedTime:E.LastUpdatedTime});return T}parseStackEvents(E){let T=[],_=E?.DescribeStackEventsResult?.StackEvents?.member||E?.StackEvents?.member||E?.StackEvents||[];if(_&&!Array.isArray(_))_=[_];for(let d of _)if(d.LogicalResourceId)T.push({Timestamp:d.Timestamp,ResourceType:d.ResourceType,LogicalResourceId:d.LogicalResourceId,ResourceStatus:d.ResourceStatus,ResourceStatusReason:d.ResourceStatusReason});return T}async waitForStackWithProgress(E,T,_){let d={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},R=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],h=d[T],r=360,N=0,A=new Set;while(N<360)try{if(_)try{let O=[...(await this.describeStackEvents(E)).StackEvents||[]].reverse();for(let U of O){let D=`${U.LogicalResourceId}-${U.ResourceStatus}-${U.Timestamp}`;if(!A.has(D))A.add(D),_({resourceId:U.LogicalResourceId,resourceType:U.ResourceType,status:U.ResourceStatus,reason:U.ResourceStatusReason,timestamp:U.Timestamp})}}catch{}let S=await this.describeStacks({stackName:E});if(S.Stacks.length===0){if(T==="stack-delete-complete")return;await new Promise((t)=>setTimeout(t,2000)),N++;continue}let L=S.Stacks[0];if(h.includes(L.StackStatus))return;if(L.StackStatus==="DELETE_FAILED"&&T==="stack-delete-complete"){let t=Error("Stack deletion failed - may have resources that need to be retained");throw t.code="DELETE_FAILED",t.stackStatus=L.StackStatus,t.statusReason=L.StackStatusReason,t}if(R.includes(L.StackStatus))throw Error(`Stack reached failure status: ${L.StackStatus}`);await new Promise((t)=>setTimeout(t,3000)),N++}catch(S){if(T==="stack-delete-complete"&&S.message?.includes("does not exist"))return;if(T==="stack-create-complete"&&S.message?.includes("does not exist")){await new Promise((L)=>setTimeout(L,2000)),N++;continue}throw S}throw Error(`Timeout waiting for stack to reach ${T}`)}async waitForStackComplete(E,T=120,_=5000){let d=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],R=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let h=0;h<T;h++)try{let r=await this.describeStacks({stackName:E});if(r.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let N=r.Stacks[0],A=N.StackStatus;if(d.includes(A))return{success:!0,status:A};if(R.includes(A))return{success:!1,status:A,reason:N.StackStatusReason};await new Promise((S)=>setTimeout(S,_))}catch(r){if(r.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw r}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}var e_=cE(()=>{VE()});import{homedir as Q3}from"node:os";import{join as M3}from"node:path";function Hy(E){return E.startsWith("~/")?M3(Q3(),E.slice(2)):E}function OS(...E){for(let T of E){let _=process.env[T]?.trim();if(_)return _}return}function US(...E){for(let T of E){let _=T?.trim();if(_)return _}return}function AX(E,T){return US(E,T?.hetzner?.apiToken,OS("HCLOUD_TOKEN","HETZNER_API_TOKEN"))}function SX(E,T){return US(T,E?.hetzner?.location,OS("HCLOUD_LOCATION","HETZNER_LOCATION"))??B$.location}function Kt(E,T){let _=E?.infrastructure?.compute;return US(T,_?.image,E?.hetzner?.image,OS("HCLOUD_IMAGE","HETZNER_IMAGE"))??B$.image}function V3(E,T){return US(T,E?.hetzner?.sshUser,OS("HCLOUD_SSH_USER","HETZNER_SSH_USER"))??B$.sshUser}function yy(E,T){return Hy(US(T,E?.hetzner?.sshPrivateKeyPath,OS("HCLOUD_SSH_KEY","HETZNER_SSH_KEY"))??B$.sshPrivateKeyPath)}function K3(E,T,_){let d=US(T,E?.hetzner?.sshPublicKeyPath,OS("HCLOUD_SSH_PUBLIC_KEY","HETZNER_SSH_PUBLIC_KEY"));if(d)return Hy(d);return`${_??yy(E)}.pub`}function $S(E,T={}){let _=yy(E,T.sshPrivateKeyPath);return{apiToken:AX(T.apiToken,E),location:SX(E,T.location),image:Kt(E,T.image),sshUser:V3(E,T.sshUser),sshPrivateKeyPath:_,sshPublicKeyPath:K3(E,T.sshPublicKeyPath,_)}}var B$;var ft=cE(()=>{B$={location:"fsn1",image:"ubuntu-24.04",sshUser:"root",sshPrivateKeyPath:"~/.ssh/id_ed25519"}});class Wh{name="hetzner";apiToken;baseUrl;fetchImpl;constructor(E){this.apiToken=E.apiToken,this.baseUrl=E.baseUrl??f3,this.fetchImpl=E.fetchImpl??fetch}async request(E,T,_){let d=await this.fetchImpl(`${this.baseUrl}${T}`,{method:E,headers:{Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},body:_===void 0?void 0:JSON.stringify(_)}),R=await d.text(),h;try{h=R?JSON.parse(R):{}}catch{if(!d.ok){let r=R.trim().slice(0,200)||d.statusText||"Hetzner API error";throw Error(`Hetzner API ${E} ${T} (${d.status}): ${r}`)}throw Error(`Hetzner API ${E} ${T}: unexpected non-JSON response`)}if(!d.ok){let r=h.error?.message||d.statusText||"Hetzner API error",N=h.error?.code?` [${h.error.code}]`:"";throw new W$(`Hetzner API ${E} ${T} (${d.status})${N}: ${r}`,d.status,h.error?.code,h.error?.details)}return h}async requestAll(E,T){let _=[],d=1;for(;;){let R=E.includes("?")?"&":"?",h=await this.request("GET",`${E}${R}per_page=50&page=${d}`);_.push(...h[T]??[]);let r=h.meta?.pagination?.next_page;if(!r)return _;d=r}}async listServers(){return this.requestAll("/servers","servers")}async getServer(E){return(await this.request("GET",`/servers/${E}`)).server}async getServerMetrics(E,T){let _=new URLSearchParams({type:T.types.join(","),start:T.start.toISOString(),end:T.end.toISOString(),step:String(Math.max(60,Math.floor(T.step??60)))});return(await this.request("GET",`/servers/${E}/metrics?${_}`)).metrics}async listServerTypes(E){let T=E?`?name=${encodeURIComponent(E)}`:"";return this.requestAll(`/server_types${T}`,"server_types")}async getServerType(E){return(await this.listServerTypes(E)).find((T)=>T.name===E)??null}async createServer(E){let T=await this.request("POST","/servers",{name:E.name,server_type:E.serverType,image:E.image,location:E.location,datacenter:E.datacenter,ssh_keys:E.sshKeys,user_data:E.userData,labels:E.labels,firewalls:E.firewalls,networks:E.networks,start_after_create:!0});return{server:T.server,action:T.action}}async listNetworks(){return this.requestAll("/networks","networks")}async createNetwork(E){let T=E.ipRange??"10.0.0.0/16";return(await this.request("POST","/networks",{name:E.name,ip_range:T,subnets:[{type:"cloud",ip_range:T,network_zone:"eu-central"}],labels:E.labels})).network}async deleteNetwork(E){await this.request("DELETE",`/networks/${E}`)}async listLoadBalancers(){return this.requestAll("/load_balancers","load_balancers")}async createLoadBalancer(E){return(await this.request("POST","/load_balancers",{name:E.name,load_balancer_type:E.type??"lb11",location:E.location,network_zone:E.network?void 0:E.networkZone??"eu-central",network:E.network,labels:E.labels,targets:[{type:"label_selector",label_selector:{selector:E.labelSelector},use_private_ip:!!E.network}],services:E.services.map((_)=>({protocol:_.protocol??"tcp",listen_port:_.listenPort,destination_port:_.destinationPort,health_check:{protocol:"http",port:80,interval:15,timeout:10,retries:3,http:{path:"/",status_codes:["2??","3??"]}}}))})).load_balancer}async deleteLoadBalancer(E){await this.request("DELETE",`/load_balancers/${E}`)}async deleteServer(E){return(await this.request("DELETE",`/servers/${E}`)).action}async listFirewalls(){return this.requestAll("/firewalls","firewalls")}async createFirewall(E){let T=await this.request("POST","/firewalls",{name:E.name,rules:E.rules,labels:E.labels,apply_to:E.applyTo});return{firewall:T.firewall,actions:T.actions}}async setFirewallRules(E,T){return(await this.request("POST",`/firewalls/${E}/actions/set_rules`,{rules:T})).actions??[]}async deleteFirewall(E){await this.request("DELETE",`/firewalls/${E}`)}async applyFirewallToResources(E,T){return(await this.request("POST",`/firewalls/${E}/actions/apply_to_resources`,{apply_to:T})).actions}async listSshKeys(){return this.requestAll("/ssh_keys","ssh_keys")}async createSshKey(E){return(await this.request("POST","/ssh_keys",{name:E.name,public_key:E.publicKey,labels:E.labels})).ssh_key}async getAction(E){return(await this.request("GET",`/actions/${E}`)).action}async shutdownServer(E){return(await this.request("POST",`/servers/${E}/actions/shutdown`,{})).action}async powerOnServer(E){return(await this.request("POST",`/servers/${E}/actions/poweron`,{})).action}async changeServerType(E,T,_){return(await this.request("POST",`/servers/${E}/actions/change_type`,{server_type:T,upgrade_disk:_})).action}async waitForAction(E,T){let _=T?.pollIntervalMs??2000,d=T?.maxWaitMs??300000,R=Date.now();while(Date.now()-R<d){let h=await this.getAction(E);if(h.status==="success")return h;if(h.status==="error")throw new H$(h.error?.message||"Hetzner action failed",h);await new Promise((r)=>setTimeout(r,_))}throw Error(`Timed out waiting for Hetzner action ${E}`)}async waitForServerRunning(E,T){let _=T?.pollIntervalMs??3000,d=T?.maxWaitMs??600000,R=Date.now();while(Date.now()-R<d){let h=await this.getServer(E);if(h.status==="running")return h;await new Promise((r)=>setTimeout(r,_))}throw Error(`Timed out waiting for server ${E} to reach running state`)}async waitForServerStatus(E,T,_){let d=_?.pollIntervalMs??3000,R=_?.maxWaitMs??600000,h=Date.now();while(Date.now()-h<R){let r=await this.getServer(E);if(r.status===T)return r;await new Promise((N)=>setTimeout(N,d))}throw Error(`Timed out waiting for server ${E} to reach ${T} state`)}}function Qr(E,T){let _=AX(E,T);if(!_)throw Error("Hetzner API token required. Set hetzner.apiToken in cloud.config.ts or HCLOUD_TOKEN / HETZNER_API_TOKEN.");return _}function DS(E){let[T,_]=E.trim().split(/\s+/);return _?`${T} ${_}`:T}var f3="https://api.hetzner.cloud/v1",W$,H$;var IS=cE(()=>{ft();W$=class W$ extends Error{status;code;details;constructor(E,T,_,d){super(E);this.status=T;this.code=_;this.details=d;this.name="HetznerApiError"}};H$=class H$ extends Error{action;constructor(E,T){super(E);this.action=T;this.name="HetznerActionError"}}});function CS(E){let T=new Set([80,443,...E.sitePorts,...E.allowedPorts??[]]);if(E.allowSsh)T.add(22);return[...T].map((_)=>{return{direction:"in",protocol:"tcp",port:String(_),source_ips:["0.0.0.0/0","::/0"],description:`ts-cloud port ${_}`}})}function LX(E={}){let T=[];if(E.identityFile)T.push("-i",E.identityFile);return T.push("-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null","-o","LogLevel=ERROR","-o",`ConnectTimeout=${E.connectTimeoutSec??10}`),T}async function y$(E,T,_={}){let d=Bun.spawn(["ssh",...LX(_),`${_.user??"root"}@${E}`,T],{stdout:"pipe",stderr:"pipe"}),[R,h]=await Promise.all([new Response(d.stdout).text(),new Response(d.stderr).text()]);return{code:await d.exited,stdout:R,stderr:h}}async function id(E,T,_={}){let d=await y$(E,T,_);if(d.code!==0)throw Error(`ssh \`${T}\` on ${E} failed (${d.code}): ${d.stderr.trim()||d.stdout.trim()}`);return d.stdout}async function Y$(E,T={}){let _=T.timeoutMs??180000,d=T.pollIntervalMs??5000,R=Date.now();while(Date.now()-R<_){let h=await y$(E,"echo ready",T);if(h.code===0&&h.stdout.includes("ready"))return;await new Promise((r)=>setTimeout(r,d))}throw Error(`SSH not ready on ${E} after ${_}ms`)}function Vr(E=!0){if(!E)return[];return["export DEBIAN_FRONTEND=noninteractive","dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q 'ok installed' || apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable --now unattended-upgrades 2>/dev/null || true"]}function g3(E=!0){let T=typeof E==="object"?E:{};return{enabled:typeof E==="boolean"?E:E.enabled!==!1,cpuLoadPerCore:T.alerts?.cpuLoadPerCore??2,memPercent:T.alerts?.memPercent??90,diskPercent:T.alerts?.diskPercent??90}}function Kr(E=!0){let{enabled:T,cpuLoadPerCore:_,memPercent:d,diskPercent:R}=g3(E);if(!T)return[];let h=Gy.map(([N,A])=>`SVC_${N.toUpperCase()}=$(probe ${A})`),r=Gy.map(([N])=>`"${N}":"$SVC_${N.toUpperCase()}"`).join(",");return["if ! command -v sadf >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -y -qq sysstat; fi","systemctl enable --now sysstat.service 2>/dev/null || true","mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...h,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+r+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${_} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${_}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${d} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${R} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnCalendar=*-*-* *:*:00","AccuracySec=1s","RandomizedDelaySec=5s","Persistent=true","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable --now ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.service"]}var Gy;var Pt=cE(()=>{Gy=[["nginx",80],["https",443],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700],["typesense",8108],["smtp",25]]});function md(E,T){return`/var/www/${E}-${T}`}function Zt(E){return E.type!=null&&b3.has(E.type)}function UX(E){if(E.deploy)return E.deploy;if(Zt(E))return"server";if(E.start)return"server";return"bucket"}function vT(E){if(E.redirect)return"redirect";if(Zt(E))return"server-php";if(UX(E)==="bucket")return"bucket";return E.start?"server-app":"server-static"}function k3(E){return E.infrastructure?.compute!=null||Boolean(E.cloud?.attachTo?.trim())}function $X(E){let T=[],_=[],d=E.sites||{},R=k3(E),h=fA(E);if(h)T.push(h);let r=new Map;for(let[N,A]of Object.entries(d)){if(!A)continue;let S=UX(A),L=vT(A);if(L==="redirect"){if(!A.domain)T.push(`Site '${N}' is a redirect site but has no \`domain\` to redirect from.`);if(!(typeof A.redirect==="string"?A.redirect:A.redirect?.to))T.push(`Site '${N}' is a redirect site but has no redirect target (\`redirect\` / \`redirect.to\`).`);if(!R)T.push(`Site '${N}' is a redirect site but no \`infrastructure.compute\` is configured to host the gateway that serves the redirect.`);let O=[];if(A.start)O.push("start");if(A.root)O.push("root");if(O.length>0)_.push(`Site '${N}' is a redirect site but also sets ${O.join(", ")}. These are ignored.`);continue}if(S==="server"&&!A.start&&!A.root){T.push(`Site '${N}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);continue}if(L==="server-php"){if(!R)T.push(`Site '${N}' is a PHP site (type:'${A.type}') but no \`infrastructure.compute\` is configured. Add a server (infrastructure.compute) with PHP provisioning.`);if(!A.repository?.url)T.push(`Site '${N}' is a PHP site (type:'${A.type}') but has no \`repository.url\` to clone. PHP sites deploy via git.`)}else if(L==="server-app"){if(!R)T.push(`Site '${N}' deploys to a server (deploy:'server'${A.deploy?"":" inferred from `start`"}) but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`);if(typeof A.port==="number"){let t=r.get(A.port);if(t)T.push(`Sites '${t}' and '${N}' both use port ${A.port}. Server apps sharing a box must use distinct ports.`);else r.set(A.port,N)}}else if(L==="server-static"){if(!A.root)T.push(`Site '${N}' is a server static site (deploy:'server', no \`start\`) but has no \`root\` directory to serve.`);if(!R)T.push(`Site '${N}' deploys to a server (deploy:'server') but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`)}else{if(!A.root)T.push(`Site '${N}' deploys to a bucket but has no \`root\` directory to upload.`);let t=[];if(A.start)t.push("start");if(typeof A.port==="number")t.push("port");if(A.preStart&&A.preStart.length>0)t.push("preStart");if(t.length>0)_.push(`Site '${N}' deploys to a bucket but sets server-only field(s): ${t.join(", ")}. These are ignored. Set deploy:'server' to use them.`)}}return{errors:T,warnings:_}}function Qy(E){let T=vT(E);return T!=="bucket"&&T!=="redirect"}var b3;var fr=cE(async()=>{await mE();b3=new Set(["laravel","php","statamic","wordpress"])});function v3(E){if(typeof E==="string")return{to:E};let T={to:E.to};if(E.status!=null)T.status=E.status;if(E.preservePath!=null)T.preservePath=E.preservePath;return T}function n3(E){let T=E.auth;if(!T||T.enabled===!1||!T.password)return;return{username:T.username||"admin",password:T.password,...T.realm?{realm:T.realm}:{}}}function My(E){if(!E||E==="/")return;let T=`/${E}`.replace(/\/+/g,"/").replace(/\/+$/,"");if(!T.startsWith("/"))T=`/${T}`;return T===""||T==="/"?void 0:T}function DX(E,T){let d=(T?`${E}${T}`:E).replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return d.length>0?d:"rpx"}function l3(E,T){if(!T||T.length===0)return`localhost:${E}`;return T.map((_)=>`${_.privateIp??_.publicIp}:${E}`)}function Vy(E,T,_){let d=(T.wwwRoot??"/var/www").replace(/\/+$/,""),R=T.slug??"app",h=T.proxy.certsDir??CX,r=T.proxy.loadBalancer,N=[],A=new Set;for(let[t,O]of Object.entries(E)){if(!O||!O.domain)continue;let U=vT(O);if(U==="bucket")continue;let D=My(O.path),C=DX(O.domain,D),w=n3(O);if(U==="redirect"){N.push({to:O.domain,path:D,redirect:v3(O.redirect),id:C,...w?{auth:w}:{}}),A.add(O.domain);continue}if(U==="server-app"){if(typeof O.port!=="number")continue;let c=l3(O.port,_);N.push({to:O.domain,path:D,from:c,id:C,...w?{auth:w}:{},...Array.isArray(c)&&r?{loadBalancer:r}:{}})}else N.push({to:O.domain,path:D,static:{dir:`${d}/${R}-${t}/current`,spa:O.spa??!1,pathRewriteStyle:O.pathRewriteStyle??"directory"},cleanUrls:O.pathRewriteStyle!=="flat",...w?{auth:w}:{},id:C});A.add(O.domain)}if(T.proxy.autoWww!==!1)for(let t of[...A]){if(t.split(".").length!==2)continue;let O=`www.${t}`;if(A.has(O))continue;N.push({to:O,redirect:{to:`https://${t}`},id:DX(O)}),A.add(O)}N.sort((t,O)=>{if(t.to!==O.to)return t.to.localeCompare(O.to);return(O.path?.length??0)-(t.path?.length??0)});let S={proxies:N,productionCerts:{certsDir:h},https:!0,hostsManagement:!1,cleanup:{hosts:!1,certs:!1}};if(T.proxy.onDemandTls&&A.size>0)S.onDemandTls={enabled:!0,allowedSuffixes:[...A],email:T.proxy.onDemandTlsEmail,certsDir:h,staging:T.proxy.onDemandTlsStaging??!1};if(T.proxy.onDemandTls)S.acmeChallengeWebroot=T.proxy.acmeWebroot??u3;let L=T.proxy.cdn;if(L?.secret&&L.frontedHosts.length>0)S.originGuard={header:L.secretHeader??"X-Origin-Verify",value:L.secret,hosts:L.frontedHosts};return S}function Pr(E,T){return Vy(E,T)}function cS(E,T,_){return Vy(E,_,T)}function Nd(E){return E?.webServer==="rpx"||E?.proxy?.engine==="rpx"}function i3(E=wS,T=CX){return`// Generated by ts-cloud — rpx gateway assembler.
8390
8390
  // Merges every app's fragment in ${E} so independent deploys compose
8391
8391
  // without clobbering each other. Each deploy writes only its own <slug>.json.
8392
8392
  import { startProxies } from '@stacksjs/rpx'
@@ -9195,7 +9195,7 @@ Run \`${this.name??"cli"} --help\` for usage.`;Sr.stderr.write(`${h}${R}${r}
9195
9195
  `).length-1;this.output.write(Ah.move(-999,E*-1))}render(){let E=Xj(this._render(this)??"",cj.stdout.columns,{hard:!0,trim:!1});if(E===this._prevFrame)return;if(this.state==="initial")this.output.write(Ah.hide);else{let T=fM(this._prevFrame,E);if(this.restoreCursor(),T&&T?.length===1){let _=T[0];this.output.write(Ah.move(0,_)),this.output.write(k1.lines(1));let d=E.split(`
9196
9196
  `);this.output.write(d[_]),this._prevFrame=E,this.output.write(Ah.move(0,d.length-_-1));return}if(T&&T?.length>1){let _=T[0];this.output.write(Ah.move(0,_)),this.output.write(k1.down());let R=E.split(`
9197
9197
  `).slice(_);this.output.write(R.join(`
9198
- `)),this._prevFrame=E;return}this.output.write(k1.down())}if(this.output.write(E),this.state==="initial")this.state="active";this._prevFrame=E}}function bM(E,T){if(E===void 0)return 0;if(T.length===0)return 0;let d=T.findIndex((R)=>R.value===E);return d!==-1?d:0}function kM(E,T){return(T.label??String(T.value)).toLowerCase().includes(E.toLowerCase())}function uM(E,T){if(!T)return;if(E)return T;return T[0]}class vM extends m1{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#E=0;#_="";#d;#T;get cursor(){return this.#E}get userInputWithCursor(){if(!this.userInput)return GO.inverse(GO.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let E=this.userInput.slice(0,this._cursor),[T,..._]=this.userInput.slice(this._cursor);return`${E}${GO.inverse(T)}${_.join("")}`}get options(){if(typeof this.#T==="function")return this.#T();return this.#T}constructor(E){super(E);this.#T=E.options;let T=this.options;this.filteredOptions=[...T],this.multiple=E.multiple===!0,this.#d=E.filter??kM;let _;if(E.initialValue&&Array.isArray(E.initialValue))if(this.multiple)_=E.initialValue;else _=E.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)_=[this.options[0].value];if(_)for(let d of _){let R=T.findIndex((h)=>h.value===d);if(R!==-1)this.toggleSelected(d),this.#E=R}this.focusedValue=this.options[this.#E]?.value,this.on("key",(d,R)=>this.#R(d,R)),this.on("userInput",(d)=>this.#h(d))}_isActionKey(E,T){return E==="\t"||this.multiple&&this.isNavigating&&T.name==="space"&&E!==void 0&&E!==""}#R(E,T){let _=T.name==="up",d=T.name==="down",R=T.name==="return";if(_||d){if(this.#E=Math.max(0,Math.min(this.#E+(_?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#E]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(R)this.value=uM(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(T.name==="tab"||this.isNavigating&&T.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected(E){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes(E))this.selectedValues=this.selectedValues.filter((T)=>T!==E);else this.selectedValues=[...this.selectedValues,E];else this.selectedValues=[E]}#h(E){if(E!==this.#_){this.#_=E;let T=this.options;if(E)this.filteredOptions=T.filter((_)=>this.#d(E,_));else this.filteredOptions=[...T];if(this.#E=bM(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#E]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class nM extends m1{options;cursor=0;#E;getGroupItems(E){return this.options.filter((T)=>T.group===E)}isGroupSelected(E){let T=this.getGroupItems(E),_=this.value;if(_===void 0)return!1;return T.every((d)=>_.includes(d.value))}toggleValue(){let E=this.options[this.cursor];if(this.value===void 0)this.value=[];if(E.group===!0){let T=String(E.value),_=this.getGroupItems(T);if(this.isGroupSelected(T))this.value=this.value.filter((d)=>_.findIndex((R)=>R.value===d)===-1);else this.value=[...this.value,..._.map((d)=>d.value)];this.value=Array.from(new Set(this.value))}else{let T=this.value.includes(E.value);this.value=T?this.value.filter((_)=>_!==E.value):[...this.value,E.value]}}constructor(E){super(E,!1);let{options:T}=E;this.#E=E.selectableGroups!==!1,this.options=Object.entries(T).flatMap(([_,d])=>[{value:_,group:!0,label:_},...d.map((R)=>({...R,group:_}))]),this.value=[...E.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:_})=>_===E.cursorAt),this.#E?0:1),this.on("cursor",(_)=>{switch(_){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let d=this.options[this.cursor]?.group===!0;if(!this.#E&&d)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let d=this.options[this.cursor]?.group===!0;if(!this.#E&&d)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var lM=TM();var WT=(E,T)=>lM?E:T,Ip=WT("◆","*"),Cp=WT("■","x"),wp=WT("▲","x"),cp=WT("◇","o"),Xp=WT("┌","T"),iM=WT("│","|"),Jp=WT("└","—"),Fp=WT("●",">"),zp=WT("○"," "),jp=WT("◻","[•]"),Bp=WT("◼","[+]"),Wp=WT("◻","[ ]"),Hp=WT("▪","•"),yp=WT("─","-"),Yp=WT("╮","+"),ep=WT("├","+"),Gp=WT("╯","+"),Qp=WT("●","•"),Mp=WT("◆","*"),Vp=WT("▲","!"),Kp=WT("■","x");var fp={light:WT("─","-"),heavy:WT("━","="),block:WT("█","#")};function mM(){return`${GO.gray(iM)} `}var Pp=mM();var a1="0.7.73";ME();import{existsSync as hI}from"node:fs";import{mkdir as r4,writeFile as Zj}from"node:fs/promises";function rI(E){E.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(b("Initializing ts-cloud Project"),hI("cloud.config.ts")){if(!await $E("cloud.config.ts already exists. Overwrite?",!1)){$("Initialization cancelled");return}}let _=T?.name||await LT("Project name","my-app"),d=T?.mode||await VO("Select deployment mode",["serverless","server"]),R=T?.region||await VO("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),h=new n("Creating configuration file...");h.start();let r=`import { defineConfig } from '@ts-cloud/core'
9198
+ `)),this._prevFrame=E;return}this.output.write(k1.down())}if(this.output.write(E),this.state==="initial")this.state="active";this._prevFrame=E}}function bM(E,T){if(E===void 0)return 0;if(T.length===0)return 0;let d=T.findIndex((R)=>R.value===E);return d!==-1?d:0}function kM(E,T){return(T.label??String(T.value)).toLowerCase().includes(E.toLowerCase())}function uM(E,T){if(!T)return;if(E)return T;return T[0]}class vM extends m1{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#E=0;#_="";#d;#T;get cursor(){return this.#E}get userInputWithCursor(){if(!this.userInput)return GO.inverse(GO.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let E=this.userInput.slice(0,this._cursor),[T,..._]=this.userInput.slice(this._cursor);return`${E}${GO.inverse(T)}${_.join("")}`}get options(){if(typeof this.#T==="function")return this.#T();return this.#T}constructor(E){super(E);this.#T=E.options;let T=this.options;this.filteredOptions=[...T],this.multiple=E.multiple===!0,this.#d=E.filter??kM;let _;if(E.initialValue&&Array.isArray(E.initialValue))if(this.multiple)_=E.initialValue;else _=E.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)_=[this.options[0].value];if(_)for(let d of _){let R=T.findIndex((h)=>h.value===d);if(R!==-1)this.toggleSelected(d),this.#E=R}this.focusedValue=this.options[this.#E]?.value,this.on("key",(d,R)=>this.#R(d,R)),this.on("userInput",(d)=>this.#h(d))}_isActionKey(E,T){return E==="\t"||this.multiple&&this.isNavigating&&T.name==="space"&&E!==void 0&&E!==""}#R(E,T){let _=T.name==="up",d=T.name==="down",R=T.name==="return";if(_||d){if(this.#E=Math.max(0,Math.min(this.#E+(_?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#E]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(R)this.value=uM(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(T.name==="tab"||this.isNavigating&&T.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected(E){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes(E))this.selectedValues=this.selectedValues.filter((T)=>T!==E);else this.selectedValues=[...this.selectedValues,E];else this.selectedValues=[E]}#h(E){if(E!==this.#_){this.#_=E;let T=this.options;if(E)this.filteredOptions=T.filter((_)=>this.#d(E,_));else this.filteredOptions=[...T];if(this.#E=bM(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#E]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class nM extends m1{options;cursor=0;#E;getGroupItems(E){return this.options.filter((T)=>T.group===E)}isGroupSelected(E){let T=this.getGroupItems(E),_=this.value;if(_===void 0)return!1;return T.every((d)=>_.includes(d.value))}toggleValue(){let E=this.options[this.cursor];if(this.value===void 0)this.value=[];if(E.group===!0){let T=String(E.value),_=this.getGroupItems(T);if(this.isGroupSelected(T))this.value=this.value.filter((d)=>_.findIndex((R)=>R.value===d)===-1);else this.value=[...this.value,..._.map((d)=>d.value)];this.value=Array.from(new Set(this.value))}else{let T=this.value.includes(E.value);this.value=T?this.value.filter((_)=>_!==E.value):[...this.value,E.value]}}constructor(E){super(E,!1);let{options:T}=E;this.#E=E.selectableGroups!==!1,this.options=Object.entries(T).flatMap(([_,d])=>[{value:_,group:!0,label:_},...d.map((R)=>({...R,group:_}))]),this.value=[...E.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:_})=>_===E.cursorAt),this.#E?0:1),this.on("cursor",(_)=>{switch(_){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let d=this.options[this.cursor]?.group===!0;if(!this.#E&&d)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let d=this.options[this.cursor]?.group===!0;if(!this.#E&&d)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var lM=TM();var WT=(E,T)=>lM?E:T,Ip=WT("◆","*"),Cp=WT("■","x"),wp=WT("▲","x"),cp=WT("◇","o"),Xp=WT("┌","T"),iM=WT("│","|"),Jp=WT("└","—"),Fp=WT("●",">"),zp=WT("○"," "),jp=WT("◻","[•]"),Bp=WT("◼","[+]"),Wp=WT("◻","[ ]"),Hp=WT("▪","•"),yp=WT("─","-"),Yp=WT("╮","+"),ep=WT("├","+"),Gp=WT("╯","+"),Qp=WT("●","•"),Mp=WT("◆","*"),Vp=WT("▲","!"),Kp=WT("■","x");var fp={light:WT("─","-"),heavy:WT("━","="),block:WT("█","#")};function mM(){return`${GO.gray(iM)} `}var Pp=mM();var a1="0.7.75";ME();import{existsSync as hI}from"node:fs";import{mkdir as r4,writeFile as Zj}from"node:fs/promises";function rI(E){E.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(b("Initializing ts-cloud Project"),hI("cloud.config.ts")){if(!await $E("cloud.config.ts already exists. Overwrite?",!1)){$("Initialization cancelled");return}}let _=T?.name||await LT("Project name","my-app"),d=T?.mode||await VO("Select deployment mode",["serverless","server"]),R=T?.region||await VO("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),h=new n("Creating configuration file...");h.start();let r=`import { defineConfig } from '@ts-cloud/core'
9199
9199
 
9200
9200
  export default defineConfig({
9201
9201
  project: {
@@ -9609,7 +9609,7 @@ Resources to create: ${W}`);let G={};for(let e of Object.values(S.Resources||{})
9609
9609
  No changes detected - infrastructure is up to date`);return}if($(`
9610
9610
  Changes detected:
9611
9611
  `),w.length>0){Z(`Resources to add (${w.length}):`);for(let j of w){let W=U[j].Type;$(` + ${j} (${W})`)}console.log()}if(c.length>0){Q(`Resources to remove (${c.length}):`);for(let j of c){let W=O[j].Type;$(` - ${j} (${W})`)}console.log()}if(z.length>0){dE(`Resources to modify (${z.length}):`);for(let j of z){let W=U[j].Type;$(` ~ ${j} (${W})`)}console.log()}$("Summary:"),$(` - Add: ${w.length}`),$(` - Remove: ${c.length}`),$(` - Modify: ${z.length}`),$("\nRun `cloud deploy` to apply these changes")}catch(_){Q(`Diff failed: ${_.message}`)}})}ME();await mE();IS();ft();function Mr(E,T=0){let _=Number(E);return Number.isFinite(_)?_:T}function tX(E){return Mr(E)*1024}function P3(E){let T=E?.date?.trim(),_=E?.time?.trim();if(!T||!_)return null;let d=new Date(`${T}T${_}Z`);return Number.isFinite(d.getTime())?d.toISOString():null}function Z3(E,T,_){let d;try{d=JSON.parse(E)}catch{return[]}let R=(d?.sysstat?.hosts??[]).flatMap((r)=>r.statistics??[]),h=[];for(let r of R){let N=P3(r.timestamp);if(!N)continue;let A=new Date(N).getTime();if(A<T.getTime()||A>_.getTime())continue;let S=r["cpu-load"]?.find((t)=>t.cpu==="all")??r["cpu-load"]?.[0],L=Mr(S?.idle,100);h.push({timestamp:N,cpuUsedPercent:Math.max(0,Math.min(100,100-L)),cpuUserPercent:Mr(S?.user),cpuSystemPercent:Mr(S?.system),cpuIowaitPercent:Mr(S?.iowait),memoryUsedPercent:Mr(r.memory?.["memused-percent"]),memoryUsedBytes:tX(r.memory?.memused),memoryAvailableBytes:tX(r.memory?.avail),swapUsedPercent:Mr(r.memory?.["swpused-percent"]),swapUsedBytes:tX(r.memory?.swpused)})}return h.sort((r,N)=>r.timestamp.localeCompare(N.timestamp))}function q3(E){return Object.fromEntries(Object.entries(E.time_series??{}).map(([T,_])=>[T,(_.values??[]).map(([d,R])=>({timestamp:new Date(Number(d)*1000).toISOString(),value:Mr(R,Number.NaN)})).filter((d)=>Number.isFinite(d.value))]))}function Yy(E){return E.length?E.reduce((T,_)=>T+_,0)/E.length:null}function OX(E){return E.length?Math.max(...E):null}function x3(E){return E.length?Math.min(...E):null}async function ey(E){let[T,_]=await Promise.all([E.client.getServerMetrics(E.serverId,{types:["cpu","disk","network"],start:E.from,end:E.to,step:E.step}),id(E.remote.host,"LC_ALL=C sadf -j -- -u -r -S",E.remote).catch(()=>"")]),d=Z3(_,E.from,E.to),R=q3(T),r=(R.cpu??[]).map((t)=>Math.max(0,Math.min(100,t.value/Math.max(1,E.cores)))),N=d.map((t)=>t.cpuUsedPercent),A=r.length?r:N,S=d.map((t)=>t.memoryUsedPercent),L=d.map((t)=>t.swapUsedPercent);return{from:E.from.toISOString(),to:E.to.toISOString(),cores:E.cores,host:d,provider:R,summary:{cpuAveragePercent:Yy(A),cpuPeakPercent:OX(A),memoryAveragePercent:Yy(S),memoryPeakPercent:OX(S),memoryMinimumAvailableBytes:x3(d.map((t)=>t.memoryAvailableBytes)),swapPeakPercent:OX(L)}}}BX();yX();GX();KX();K$();await QR([zX(),qr()]);import{createHash as Xb}from"node:crypto";var vy=async(E)=>{let T=Bun.spawn(E,{stdout:"pipe",stderr:"pipe"}),[_,d,R]=await Promise.all([T.exited,new Response(T.stdout).text(),new Response(T.stderr).text()]);return{code:_,stdout:d,stderr:R}};class ny{async scan(E,T){let _=await vy(["ssh-keyscan","-T","10","-p",String(T),"-t","ed25519",E]),d=_.stdout.split(`
9612
- `).find((R)=>R&&!R.startsWith("#"))?.trim().split(/\s+/);if(_.code!==0||!d?.[1]||!d[2])throw Error(`SSH host-key scan failed: ${_.stderr.trim()||"no key returned"}`);return{algorithm:d[1],key:d[2]}}async exec(E,T){if(E.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return vy(["ssh","-p",String(E.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${E.sshUser}@${E.endpoint}`,T])}}var Jb=(E)=>`SHA256:${Xb("sha256").update(Buffer.from(E,"base64")).digest("base64").replace(/=+$/,"")}`,Fb=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class eh{provider;transport;discoverer;constructor(E,T=new ny,_){this.provider=E;this.transport=T;this.discoverer=_}discover(E){return this.discoverer?.(E)??Promise.resolve([])}async test(E){try{let T=await this.transport.scan(E.endpoint,E.sshPort);return{reachable:!0,hostKeyAlgorithm:T.algorithm,hostKeyFingerprint:Jb(T.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(E){let T=await this.transport.exec(E,Fb);if(T.code!==0)throw Error(`Fleet validation failed: ${T.stderr.trim()||T.code}`);try{return JSON.parse(T.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(E,T){let _=await this.transport.exec(E,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${T.length}`);if(_.code!==0)throw Error(`Fleet bootstrap failed: ${_.stderr.trim()||_.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function ly(E,T){return{"fleet.bootstrap":async(_)=>{let d=_.operation.input&&typeof _.operation.input==="object"&&!Array.isArray(_.operation.input)?_.operation.input:{},R=E.get(String(d.serverId??""));if(!R)throw Error("Queued fleet server was not found.");let h=T.find((A)=>A.provider===R.provider);if(!h)throw Error(`No ${R.provider} fleet driver is configured.`);let r=Array.isArray(d.steps)?d.steps.map(String):[];if(_.checkpoint("preflight","Rechecking pinned trust and healthy validation."),R.trustState!=="pinned"||!R.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");_.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let N=await h.bootstrap(R,r);return E.update(R.id,{bootstrapVersion:N.version,status:"ready"}),_.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:R.id,bootstrapVersion:N.version,steps:r.length}}}}var vR=(E)=>E==null?void 0:String(E),PN=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},fX=(E)=>({id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),resourceId:String(E.resource_id),name:String(E.name),provider:String(E.provider),providerId:vR(E.provider_id),region:vR(E.region),zone:vR(E.zone),endpoint:String(E.endpoint),sshUser:String(E.ssh_user),sshPort:Number(E.ssh_port),credentialRef:String(E.credential_ref),hostKeyAlgorithm:vR(E.host_key_algorithm),hostKeyFingerprint:vR(E.host_key_fingerprint),pendingHostKey:vR(E.pending_host_key),roles:PN(E.roles,[]),labels:PN(E.labels,{}),taints:PN(E.taints,[]),capacity:PN(E.capacity,{}),usage:PN(E.usage,{}),capabilities:PN(E.capabilities,{}),status:String(E.status),trustState:String(E.trust_state),validation:PN(E.validation,void 0),bootstrapVersion:vR(E.bootstrap_version),heartbeatAt:vR(E.heartbeat_at),lastSeenAt:vR(E.last_seen_at),archivedAt:vR(E.archived_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class nR{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}get(E){let T=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(E);return T?fX(T):void 0}list(E,T=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(E).map(fX).filter((_)=>T||_.status!=="archived")}findProvider(E,T,_){let d=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(E,T,_);return d?fX(d):void 0}create(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[T,E.organizationId,E.projectId,E.resourceId,E.name,E.provider,E.providerId??null,E.region??null,E.zone??null,E.endpoint,E.sshUser,E.sshPort,E.credentialRef,E.hostKeyAlgorithm??null,E.hostKeyFingerprint??null,E.pendingHostKey??null,JSON.stringify(E.roles),JSON.stringify(E.labels),JSON.stringify(E.taints),JSON.stringify(E.capacity),JSON.stringify(E.usage),JSON.stringify(E.capabilities),E.status,E.trustState,JSON.stringify(E.validation??{}),E.bootstrapVersion??null,E.heartbeatAt??null,E.lastSeenAt??null,E.archivedAt??null,_,_]),this.get(T)}update(E,T){let _=this.get(E);if(!_)throw Error("Server was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[d.name,d.providerId??null,d.region??null,d.zone??null,d.endpoint,d.sshUser,d.sshPort,d.credentialRef,d.hostKeyAlgorithm??null,d.hostKeyFingerprint??null,d.pendingHostKey??null,JSON.stringify(d.roles),JSON.stringify(d.labels),JSON.stringify(d.taints),JSON.stringify(d.capacity),JSON.stringify(d.usage),JSON.stringify(d.capabilities),d.status,d.trustState,JSON.stringify(d.validation??{}),d.bootstrapVersion??null,d.heartbeatAt??null,d.lastSeenAt??null,d.archivedAt??null,R,E]),this.get(E)}}var zb=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class gt{store;drivers;now;queue;constructor(E,T,_,d=()=>new Date){this.store=E;this.drivers=T;this.now=d;this.queue=_??new nE(E.control)}driver(E){let T=this.drivers.find((_)=>_.provider===E);if(!T)throw Error(`No ${E} fleet driver is configured.`);return T}enroll(E){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(E.name))throw Error("Server name is invalid.");if(!zb.test(E.endpoint)||E.sshUser==="root"||!E.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let T=E.providerId?this.store.findProvider(E.organizationId,E.provider,E.providerId):void 0;if(T)return this.store.update(T.id,{endpoint:E.endpoint,region:E.region,zone:E.zone});let _=this.store.control.createResource({projectId:E.projectId,kind:"server",slug:E.name,name:E.name,provider:E.provider,providerId:E.providerId}),d=this.driver(E.provider);return this.store.create({...E,resourceId:_.id,sshPort:E.sshPort??22,labels:E.labels??{},taints:[],capacity:{},usage:{},capabilities:d.capabilities(),status:"pending",trustState:"unverified"})}async test(E){let T=this.store.get(E);if(!T)throw Error("Server was not found.");let _=await this.driver(T.provider).test(T);if(!_.reachable)return this.store.update(E,{status:"unreachable"});if(T.hostKeyFingerprint&&T.hostKeyFingerprint!==_.hostKeyFingerprint)return this.store.update(E,{status:"degraded",trustState:"rotation_pending",pendingHostKey:_.hostKeyFingerprint});return this.store.update(E,{hostKeyAlgorithm:_.hostKeyAlgorithm,hostKeyFingerprint:_.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(E,T){let _=this.store.get(E);if(!_||_.pendingHostKey!==T)throw Error("Pending host key does not match.");return this.store.update(E,{hostKeyFingerprint:T,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(E){let T=this.store.get(E);if(!T||T.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let _=await this.driver(T.provider).validate(T),d=[];if(!["x64","arm64","x86_64","aarch64"].includes(_.arch??""))d.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let r of["curl","tar"])if(!_.tools?.[r])d.push({code:`tool.${r}`,severity:"error",message:`${r} is missing.`,remediation:`Install ${r} before bootstrap.`});if(Math.abs(_.timeSkewSeconds??0)>60)d.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!_.dnsOk)d.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let R={valid:!d.some((r)=>r.severity==="error"),facts:_,findings:d,validatedAt:this.now().toISOString(),validatorVersion:"1"},h={cpu:_.cpuCores??0,memoryBytes:_.memoryBytes??0,diskBytes:_.diskBytes??0};return this.store.update(E,{validation:R,capacity:h,status:R.valid?"ready":"degraded"})}bootstrap(E,T=!1){let _=this.store.get(E);if(!_?.validation?.valid)throw Error("A healthy validation report is required.");let d=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!T)return{preview:!0,steps:d};let R=this.queue.enqueue({projectId:_.projectId,resourceId:_.resourceId,kind:"fleet.bootstrap",input:{serverId:E,steps:d},lockKey:`server:${E}`,providerKey:_.provider}).operation;return{preview:!1,steps:d,operation:R}}heartbeat(E,T){let _=this.store.get(E);if(!_)throw Error("Server was not found.");let d=this.now().toISOString();return this.store.update(E,{usage:T.usage,capabilities:T.capabilities??_.capabilities,heartbeatAt:d,lastSeenAt:d,status:_.status==="draining"||_.status==="drained"?_.status:"ready"})}drain(E,T=!1){return this.store.update(E,{status:T?"drained":"draining"})}uncordon(E){return this.store.update(E,{status:"ready"})}archive(E,T){let _=this.store.get(E);if(!_||T!==_.name)throw Error("Exact server name confirmation is required.");return this.store.update(E,{status:"archived",archivedAt:this.now().toISOString()})}}async function jb(){let E=await o(),T=lE(process.cwd(),E),_=new nR(T.store),d=new gt(_,[new eh("aws"),new eh("hetzner"),new eh("ssh")]);return{controlPlane:T,store:_,service:d}}async function Gh(E){let T=await jb();try{return await E(T)}finally{T.controlPlane.store.close()}}var ZN=(E,T)=>{let _=E.store.list(E.controlPlane.project.id).find((d)=>d.id===T||d.name===T);if(!_)throw Error(`Server ${T} was not found.`);return _},sd=(E)=>{Q(E instanceof Error?E.message:String(E)),process.exitCode=1};function PX(E,T){let _=Number.parseInt(E??"",10);return Number.isFinite(_)&&_>=0?_:T}function Bb(E="3h"){let T=E.match(/^(\d+)(m|h)$/);if(!T)throw Error("--range must use minutes or hours, for example 30m or 3h.");let _=Number(T[1])*(T[2]==="h"?3600000:60000);if(_<300000||_>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return _}function bt(E,T="%"){return E==null?"unavailable":`${E.toFixed(1)}${T}`}async function Wb(E,T){let _=await o();if(_.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let d=T.env??process.env.CLOUD_ENV??"production",R=IT(_,d),h=await IR(R);if(!h?.serverId)throw Error(`No pinned Hetzner server was found for ${R}.`);if(![h.serverName,String(h.serverId),h.stackName].includes(E))throw Error(`Refusing to read ${E}: project state is pinned to ${h.serverName}.`);let r=$S(_),N=new Wh({apiToken:Qr(r.apiToken,_)}),A=await N.getServer(h.serverId),S=h.publicIp??A.public_net.ipv4?.ip;if(!S)throw Error(`Server ${A.name} has no public IPv4 address.`);let L=new Date,t=new Date(L.getTime()-Bb(T.range)),O=Math.min(3600,Math.max(60,PX(T.step,60))),U=await ey({client:N,serverId:A.id,cores:Math.max(1,Number(A.server_type.cores)||1),from:t,to:L,step:O,remote:{host:S,user:h.sshUser??r.sshUser,identityFile:r.sshPrivateKeyPath,connectTimeoutSec:15}});if(T.json){console.log(JSON.stringify({schemaVersion:1,server:A.name,result:U},null,2));return}EE(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[A.name,`${U.from} to ${U.to}`,`${bt(U.summary.cpuAveragePercent)} / ${bt(U.summary.cpuPeakPercent)}`,`${bt(U.summary.memoryAveragePercent)} / ${bt(U.summary.memoryPeakPercent)}`,U.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(U.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,bt(U.summary.swapPeakPercent)]])}function iy(E){let T=E.targetType.prices?.find((_)=>_.location===E.location);return{serverId:E.serverId,serverName:E.serverName,location:E.location,from:E.currentType.name,to:E.targetType.name,capacityAvailable:E.capacityAvailable,alreadyComplete:E.alreadyComplete,upgradeDisk:E.upgradeDisk,target:{cores:E.targetType.cores,memoryGb:E.targetType.memory,diskGb:E.targetType.disk,architecture:E.targetType.architecture,cpuType:E.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 Hb(E){let T=iy(E);EE(["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 yb(E,T,_){let d=await o();if(d.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let R=_.env??process.env.CLOUD_ENV??"production",h=IT(d,R),r=await IR(h),N=$S(d),A=new Wh({apiToken:Qr(N.apiToken,d)}),L=r&&(E===r.serverName||E===String(r.serverId)||E===r.stackName)?await A.getServer(r.serverId):(await A.listServers()).find((e)=>e.name===E||String(e.id)===E);if(!L)throw Error(`Hetzner server ${E} was not found.`);if(r?.serverId&&r.serverId!==L.id)throw Error(`Refusing to resize ${E}: project state is pinned to server ${r.serverId}.`);let t=Hh(T),O=_.upgradeDisk!==!1,U=await xt(A,L.id,t,O);if(_.json)console.log(JSON.stringify({schemaVersion:1,plan:iy(U)},null,2));else Hb(U);if(!_.apply){if(!_.json)$(`Preview only. Re-run with --apply --confirm ${L.name} to execute.`);return}if(_.confirm!==L.name)throw Error(`Resize requires --confirm ${L.name}.`);let D=r?.publicIp??L.public_net.ipv4?.ip;if(!D)throw Error(`Server ${L.name} has no public IPv4 address for verification.`);let C={host:D,user:r?.sshUser??N.sshUser,identityFile:N.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},w=await MX(h),c=new Date().toISOString(),z={schemaVersion:1,operationId:w?.targetType===t&&w.serverId===L.id?w.operationId:crypto.randomUUID(),stackName:h,serverId:L.id,serverName:L.name,sourceType:U.currentType.name,targetType:t,upgradeDisk:O,phase:"planning",status:"running",attempts:w?.targetType===t?w.attempts:0,startedAt:w?.targetType===t?w.startedAt:c,updatedAt:c,manifest:w?.targetType===t?w.manifest:void 0};await Yh(z);let j=PX(_.pollSeconds,900)*1000,W=PX(_.maxWaitMinutes,0)*60000,G=Date.now();for(;;){let e=await xt(A,L.id,t,O);if(!e.capacityAvailable&&!e.alreadyComplete){if(z={...z,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await Yh(z),!_.wait){if(!_.json)$(`${t} has no capacity in ${e.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(W>0&&Date.now()-G>=W)throw Error(`Timed out waiting for ${t} capacity in ${e.location}.`);if(!_.json)$(`Waiting ${Math.round(j/1000)} seconds for ${t} capacity...`);await Bun.sleep(j);continue}let V=await VX(h);try{let P=await(async()=>{try{return z={...z,status:"running",attempts:z.attempts+1,updatedAt:new Date().toISOString()},await Yh(z),await HX({client:A,serverId:L.id,targetType:t,upgradeDisk:O,resumeFromOff:z.phase==="shutting-down"||z.phase==="resizing"||z.phase==="powering-on"||z.phase==="verifying",manifest:z.manifest,hooks:{preflight:async()=>{let g=await YX(C);return z={...z,manifest:g,updatedAt:new Date().toISOString()},await Yh(z),g},afterBoot:async(g,k,v,TE)=>eX(C,k,v,TE),onPhase:async(g,k)=>{if(z={...z,phase:g,status:g==="waiting-capacity"?"waiting-capacity":g==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await Yh(z),!_.json)$(`${g}${k?` ${JSON.stringify(k)}`:""}`)}}})}finally{await V()}})();if(z={...z,status:P.status==="completed"||P.status==="already-complete"?"completed":P.status==="recovered"?"recovered":"waiting-capacity",lastError:P.status==="recovered"?P.error:void 0,updatedAt:new Date().toISOString()},await Yh(z),_.json)console.log(JSON.stringify({schemaVersion:1,result:P},null,2));else if(P.status==="completed"||P.status==="already-complete")Z(`${L.name} is on ${t} and passed full post-boot verification.`);else if(P.status==="recovered"&&P.retryable&&_.wait){$(`Capacity race recovered safely. Waiting ${Math.round(j/1000)} seconds before retry.`),await Bun.sleep(j);continue}else if(P.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${P.error}`);return}catch(P){throw z={...z,status:"failed",lastError:P instanceof Error?P.message:String(P),updatedAt:new Date().toISOString()},await Yh(z),P}}}async function Yb(E,T){let _=await o();if(_.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let d=T.env??process.env.CLOUD_ENV??"production",R=IT(_,d),h=await IR(R);if(!h?.serverId)throw Error(`No pinned Hetzner server was found for ${R}.`);if(![h.serverName,String(h.serverId),h.stackName].includes(E))throw Error(`Refusing to optimize ${E}: project state is pinned to ${h.serverName}.`);let r=$S(_),N=new Wh({apiToken:Qr(r.apiToken,_)}),A=await N.getServer(h.serverId),S=h.publicIp??A.public_net.ipv4?.ip;if(!S)throw Error(`Server ${A.name} has no public IPv4 address.`);let L=M$(_);if(T.json)console.log(JSON.stringify({schemaVersion:1,server:A.name,plan:L},null,2));else EE(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[A.name,L.firewallPorts.join(","),L.monitoring?"on":"off",L.autoUpdates?"on":"off",`${L.swapGb} GB`,"disabled"]]);if(!T.apply){if(!T.json)$(`Preview only. Re-run with --apply --confirm ${A.name} to execute.`);return}if(T.confirm!==A.name)throw Error(`Optimization requires --confirm ${A.name}.`);let t={host:S,user:h.sshUser??r.sshUser,identityFile:r.sshPrivateKeyPath,connectTimeoutSec:15},O=await FS(t),U=O.routeProbes.filter((v)=>!v.ok),D=_.infrastructure?.compute,C=Nd(D)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,w=O.failedUnits.filter((v)=>!C.has(v));if(w.length>0)throw Error(`Preflight found failed services: ${w.join(", ")}`);if(U.length>0)throw Error(`Preflight found unhealthy routes: ${U.map((v)=>v.domain).join(", ")}`);let c=Nd(D)?[]:Object.values(_.sites??{}).flatMap((v)=>typeof v?.port==="number"&&![80,443].includes(v.port)?[v.port]:[]),z=CS({allowSsh:D?.allowSsh!==!1,sitePorts:c,allowedPorts:D?.firewall?.allowedPorts}),j=(h.firewallId?(await N.listFirewalls()).find((v)=>v.id===h.firewallId):void 0)??(await N.listFirewalls()).find((v)=>v.name===`${_.project.slug}-${d}-app-fw`);if(!j)throw Error(`Managed firewall for ${A.name} was not found.`);let W=await N.setFirewallRules(j.id,z);await Promise.all(W.map((v)=>N.waitForAction(v.id))),await XX(_,t);let[G,e]=await Promise.all([FS(t),JX(t)]),V=FX(L,e),P=fy(O,G),g=G.routeProbes.filter((v)=>!v.ok);if(P.stoppedServices.length>0)V.push(`services stopped: ${P.stoppedServices.join(", ")}`);if(P.changedRouteFragments.length>0)V.push(`route fragments changed: ${P.changedRouteFragments.join(", ")}`);if(P.missingRouteIds.length>0)V.push(`routes disappeared: ${P.missingRouteIds.join(", ")}`);if(P.changedReleaseLinks.length>0)V.push(`release links changed: ${P.changedReleaseLinks.join(", ")}`);if(P.missingData.length>0)V.push(`databases or volumes disappeared: ${P.missingData.join(", ")}`);if(g.length>0)V.push(`unhealthy routes: ${g.map((v)=>v.domain).join(", ")}`);if(V.length>0)throw Error(`Host optimization verification failed: ${V.join("; ")}`);let k={serverId:A.id,serverName:A.name,services:G.runningServices.length,routes:G.routeIds.length,healthyDomains:G.routeProbes.length,releaseLinks:G.releaseLinks.length,databasesAndVolumes:G.dataCatalog.length,report:e};if(T.json)console.log(JSON.stringify({schemaVersion:1,result:k},null,2));else Z(`${A.name} passed full host, rpx route, service, release, and data verification.`)}function ZX(E){E.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(T,_)=>{try{await Gh(async(d)=>{let R=T?[ZN(d,T)]:d.store.list(d.controlPlane.project.id),h=R.flatMap((r)=>Object.entries(r.capabilities).map(([N,A])=>({server:r.name,provider:r.provider,action:N,...A})));if(_.json)console.log(JSON.stringify({schemaVersion:1,targets:h},null,2));else EE(["Server","Provider","Action","Support","Explanation"],h.map((r)=>[r.server,r.provider,r.action,r.supported?"supported":"unsupported",r.reason??"—"]))})}catch(d){sd(d)}}),E.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,_,d)=>{try{await yb(T,_,d)}catch(R){sd(R)}}),E.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,_)=>{try{await Yb(T,_)}catch(d){sd(d)}}),E.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,_)=>{try{await Wb(T,_)}catch(d){sd(d)}}),E.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(T)=>{try{await Gh(async(_)=>{let d=_.store.list(_.controlPlane.project.id);if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],d.map((R)=>[R.name,R.providerId??"—",`${R.provider} / ${R.region??"external"}`,`${R.status} / ${R.trustState}`,R.roles.join(","),`${R.capacity.cpu??0} / ${R.capacity.memoryBytes??0}`,R.heartbeatAt??"never"]))})}catch(_){sd(_)}}),E.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,_)=>{try{await Gh(async(d)=>{let R=_.provider;if(!["aws","hetzner","ssh"].includes(R)||!_.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let h=d.service.enroll({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,provider:R,providerId:_.providerId,endpoint:_.endpoint,sshUser:_.user??"deploy",credentialRef:_.credentialRef??"secret://fleet/agent",region:_.region,roles:String(_.roles??"application").split(","),labels:Object.fromEntries(String(_.labels??"").split(",").map((r)=>r.split("=")).filter((r)=>r[0]&&r[1]))});Z(`Enrolled ${h.name} as ${h.id}; no remote mutation was performed.`)})}catch(d){sd(d)}}),E.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,_)=>{try{await Gh(async(d)=>{let R=ZN(d,T);if(R=await d.service.test(R.id),R.trustState==="rotation_pending"){if(!_.acceptHostKey)throw Error(`Host key changed to ${R.pendingHostKey}; review it first.`);R=d.service.reviewHostKey(R.id,_.acceptHostKey)}let h=await d.service.validate(R.id);if(_.json)console.log(JSON.stringify(h.validation,null,2));else EE(["Severity","Code","Finding","Remediation"],(h.validation?.findings??[]).map((r)=>[r.severity,r.code,r.message,r.remediation??"—"]));if(!h.validation?.valid)process.exitCode=1})}catch(d){sd(d)}}),E.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(T,_)=>{try{await Gh(async(d)=>{let R=d.service.bootstrap(ZN(d,T).id,!!_.apply);if(R.preview)EE(["Step"],R.steps.map((h)=>[h]));else Z(`Bootstrap queued: ${R.operation?.id}`)})}catch(d){sd(d)}}),E.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(T,_)=>{try{await Gh(async(d)=>Z(d.service.drain(ZN(d,T).id,!!_.complete).status))}catch(d){sd(d)}}),E.command("server:uncordon <name>","Return a server to scheduling").action(async(T)=>{try{await Gh(async(_)=>{_.service.uncordon(ZN(_,T).id),Z(`Uncordoned ${T}.`)})}catch(_){sd(_)}}),E.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(T,_)=>{try{await Gh(async(d)=>{d.service.archive(ZN(d,T).id,_.confirm??""),Z(`Archived ${T}; provider infrastructure was not terminated.`)})}catch(d){sd(d)}}),E.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(T)=>{try{await Gh(async(_)=>{let d=ZN(_,T);if(d.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let R=Bun.spawn(["ssh","-p",String(d.sshPort),"-o","StrictHostKeyChecking=yes",`${d.sshUser}@${d.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),h=await R.exited;if(h)process.exitCode=h})}catch(_){sd(_)}});for(let[T,_]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])E.command(T,_).action(async(...d)=>ld(T.split(" ")[0],{target:String(d[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}ME();var CR=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},Ad=(E)=>E==null?void 0:String(E),sy=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),jS=(E={})=>({...sy(),...E});function my(E){return{id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),name:String(E.name),purpose:String(E.purpose),backend:String(E.backend),region:Ad(E.region),architecture:Ad(E.architecture),labels:CR(E.labels,{}),requiredServerLabels:CR(E.required_server_labels,{}),toleratedTaints:CR(E.tolerated_taints,[]),capacity:jS(CR(E.capacity,{})),reserved:CR(E.reserved,{}),maxWorkloads:Number(E.max_workloads),costWeight:Number(E.cost_weight),spreadKey:Ad(E.spread_key),concurrency:Number(E.concurrency),ephemeralWorkspaces:Number(E.ephemeral_workspaces)===1,allowProductionSecrets:Number(E.allow_production_secrets)===1,status:String(E.status),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}function ay(E){return{id:String(E.id),projectId:String(E.project_id),environmentId:Ad(E.environment_id),resourceId:String(E.resource_id),releaseId:Ad(E.release_id),poolId:String(E.pool_id),serverId:Ad(E.server_id),purpose:String(E.purpose),requirements:CR(E.requirements,{}),decision:CR(E.decision,{}),stateful:Number(E.stateful)===1,autoReschedule:Number(E.auto_reschedule)===1,status:String(E.status),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}function eb(E){return{id:String(E.id),projectId:String(E.project_id),resourceId:Ad(E.resource_id),poolId:String(E.pool_id),placementId:Ad(E.placement_id),operationId:Ad(E.operation_id),sourceSha:String(E.source_sha),buildSpec:CR(E.build_spec,{}),credentialPolicy:CR(E.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:Ad(E.workspace),cacheKey:Ad(E.cache_key),artifactUri:Ad(E.artifact_uri),artifactDigest:Ad(E.artifact_digest),status:String(E.status),cleanupAt:Ad(E.cleanup_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}class kt{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}createPool(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[T,E.organizationId,E.projectId,E.name,E.purpose,E.backend,E.region??null,E.architecture??null,JSON.stringify(E.labels),JSON.stringify(E.requiredServerLabels),JSON.stringify(E.toleratedTaints),JSON.stringify(jS(E.capacity)),"{}",E.maxWorkloads,E.costWeight,E.spreadKey??null,E.concurrency,E.ephemeralWorkspaces?1:0,E.allowProductionSecrets?1:0,E.status,_,_]),this.getPool(T)}getPool(E){let T=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(E);return T?my(T):void 0}listPools(E){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(E).map(my)}updatePool(E,T){let _=this.getPool(E);if(!_)throw Error("Capacity pool was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.reserved),JSON.stringify(d.capacity),d.concurrency,R,E]),this.getPool(E)}addMember(E,T,_={}){let d=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[E,T,JSON.stringify(_),d,d])}members(E){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(E).map((T)=>({serverId:String(T.server_id),status:String(T.status),capacityOverride:CR(T.capacity_override,{})}))}memberStatus(E,T,_){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[_,this.now().toISOString(),E,T])}listPlacements(E,T){let _=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(E).map(ay);return T?.length?_.filter((d)=>T.includes(d.status)):_}getPlacement(E){let T=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(E);return T?ay(T):void 0}activeUsage(E,T){let _=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(E,this.now().toISOString()),d=T?_.filter((R)=>String(R.server_id)===T):_;return{resources:d.reduce((R,h)=>{let r=jS(CR(h.resources,{}));for(let N of Object.keys(R))R[N]+=r[N];return R},sy()),count:d.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(E){return this.control.transaction(()=>{this.expireLeases();let T=this.id(),_=this.id(),d=this.now().toISOString(),R=new Date(this.now().getTime()+(E.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[T,E.projectId,E.environmentId??null,E.resourceId,E.releaseId??null,E.decision.poolId,E.decision.serverId??null,E.requirements.purpose,JSON.stringify(E.requirements),JSON.stringify(E.decision),E.requirements.stateful?1:0,E.requirements.autoReschedule&&!E.requirements.stateful?1:0,d,d]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[_,T,E.decision.poolId,E.decision.serverId??null,JSON.stringify(jS(E.requirements.resources)),R,d,d]),this.getPlacement(T)})}transitionPlacement(E,T){if(!this.getPlacement(E))throw Error("Placement was not found.");let d=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[T,d,E]),["released","failed","blocked"].includes(T))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[d,E]);return this.getPlacement(E)}createBuild(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[T,E.projectId,E.resourceId??null,E.poolId,E.placementId??null,E.operationId??null,E.sourceSha,JSON.stringify(E.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:E.tokenExpiresAt}),_,_]),this.getBuild(T)}getBuild(E){let T=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(E);return T?eb(T):void 0}updateBuild(E,T){let _=this.getBuild(E);if(!_)throw Error("Remote build was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[d.operationId??null,d.workspace??null,d.cacheKey??null,d.artifactUri??null,d.artifactDigest??null,d.status,d.cleanupAt??null,R,E]),this.getBuild(E)}}var P$=["cpu","memoryBytes","diskBytes","gpu"],py=(E,T={})=>Object.entries(T).every(([_,d])=>E[_]===d),Gb=(E,T,_)=>Object.fromEntries(P$.map((d)=>[d,Math.max(0,E[d]-T[d]-(_[d]??0))])),Qb=(E,T)=>P$.every((_)=>E[_]>=(T[_]??0)),Mb=(E,T)=>P$.reduce((_,d)=>_+(T[d]??0)/(E[d]||1),0);class ut{store;fleet;constructor(E,T){this.store=E;this.fleet=T}poolCandidates(E,T,_){let d=[];for(let R of this.store.listPools(E)){if(R.id===_)continue;let h=[];if(R.status!=="active")h.push(`pool is ${R.status}`);if(R.purpose!==T.purpose)h.push(`purpose is ${R.purpose}`);if(T.region&&R.region!==T.region)h.push(`region is ${R.region??"unset"}`);if(T.architecture&&R.architecture!==T.architecture)h.push(`architecture is ${R.architecture??"unset"}`);if(!py(R.labels,T.labels))h.push("pool labels do not match");if(R.backend==="server"){let r=this.store.members(R.id);if(!r.length)d.push(this.decision(R,void 0,T,[...h,"pool has no servers"]));for(let N of r){let A=this.fleet.get(N.serverId),S=[...h];if(!A)S.push("server is missing");else this.serverReasons(R,A,N.status,T,S);d.push(this.decision(R,A,T,S,N.capacityOverride))}}else d.push(this.decision(R,void 0,T,h))}return d.sort((R,h)=>Number(h.eligible)-Number(R.eligible)||R.score.cost-h.score.cost||R.score.spread-h.score.spread||R.score.fit-h.score.fit||R.poolName.localeCompare(h.poolName)||(R.serverId??"").localeCompare(h.serverId??""))}serverReasons(E,T,_,d,R){if(_!=="active")R.push(`member is ${_}`);if(T.status!=="ready")R.push(`server is ${T.status}`);if(!T.roles.includes(d.purpose==="build"?"build":d.purpose))R.push(`server lacks ${d.purpose} role`);if(!py(T.labels,E.requiredServerLabels))R.push("server labels do not match pool selector");for(let h of T.taints)if(!E.toleratedTaints.includes(h))R.push(`taint ${h} is not tolerated`)}decision(E,T,_,d,R={}){let h=jS({...T?.capacity,...R}),r=T?Object.fromEntries(P$.map((S)=>[S,Math.min(E.capacity[S],h[S])])):E.capacity,N=this.store.activeUsage(E.id,T?.id),A=Gb(r,N.resources,E.reserved);if(N.count>=E.maxWorkloads)d.push("workload limit reached");if(_.purpose==="build"&&N.count>=E.concurrency)d.push("build concurrency reached");if(!Qb(A,_.resources))d.push("insufficient capacity");return{poolId:E.id,poolName:E.name,serverId:T?.id,eligible:d.length===0,reasons:d,available:A,score:{fit:Mb(A,_.resources),spread:N.count,cost:E.costWeight}}}explain(E,T){return this.poolCandidates(E,T)}place(E){return this.store.control.transaction(()=>{let T=this.poolCandidates(E.projectId,E.requirements).find((_)=>_.eligible);if(!T)throw Error(`No eligible capacity: ${this.explain(E.projectId,E.requirements).flatMap((_)=>_.reasons).join("; ")}`);return this.store.reserve({...E,decision:T})})}activate(E){return this.store.transitionPlacement(E,"active")}release(E){return this.store.transitionPlacement(E,"released")}drainPool(E){let T=this.store.updatePool(E,{status:"draining"}),_=[],d=[];for(let R of this.store.listPlacements(T.projectId,["reserved","active"]).filter((h)=>h.poolId===E)){if(R.stateful){d.push(this.store.transitionPlacement(R.id,"blocked"));continue}this.store.transitionPlacement(R.id,"moving");let h=this.place({projectId:R.projectId,environmentId:R.environmentId,resourceId:R.resourceId,releaseId:R.releaseId,requirements:R.requirements});_.push(this.activate(h.id)),this.store.transitionPlacement(R.id,"released")}return{pool:T,moved:_,blocked:d}}drainServer(E,T){this.store.memberStatus(E,T,"draining");let _=this.store.getPool(E);if(!_)throw Error("Capacity pool was not found.");let d=[],R=[];for(let h of this.store.listPlacements(_.projectId,["reserved","active"]).filter((r)=>r.poolId===E&&r.serverId===T)){if(h.stateful){R.push(this.store.transitionPlacement(h.id,"blocked"));continue}this.store.transitionPlacement(h.id,"moving");let r=this.poolCandidates(h.projectId,h.requirements).find((A)=>A.eligible);if(!r){R.push(this.store.transitionPlacement(h.id,"blocked"));continue}let N=this.store.reserve({projectId:h.projectId,environmentId:h.environmentId,resourceId:h.resourceId,releaseId:h.releaseId,requirements:h.requirements,decision:r});d.push(this.activate(N.id)),this.store.transitionPlacement(h.id,"released")}return{moved:d,blocked:R}}reconcileFailure(E){let T=this.fleet.get(E);if(!T)throw Error("Server was not found.");let _=[],d=[];for(let R of this.store.listPlacements(T.projectId,["active"]).filter((h)=>h.serverId===E)){if(R.stateful||!R.autoReschedule){d.push(this.store.transitionPlacement(R.id,"blocked"));continue}this.store.transitionPlacement(R.id,"failed");let h=this.place({projectId:R.projectId,environmentId:R.environmentId,resourceId:R.resourceId,releaseId:R.releaseId,requirements:R.requirements});_.push(this.activate(h.id))}return{rescheduled:_,blocked:d}}}async function Vb(){let E=await o(),T=lE(process.cwd(),E),_=new kt(T.store),d=new ut(_,new nR(T.store));return{controlPlane:T,store:_,service:d}}async function vt(E){let T=await Vb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}var Z$=(E)=>Object.fromEntries(String(E??"").split(",").map((T)=>T.split("=")).filter((T)=>T[0]&&T[1])),oy=(E)=>Object.fromEntries(Object.entries(Z$(E)).map(([T,_])=>[T,Number(_)]));function qX(E){E.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(T)=>vt((_)=>{let d=_.store.listPools(_.controlPlane.project.id);if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],d.map((R)=>[R.name,R.purpose,R.backend,`${R.region??"any"} / ${R.architecture??"any"}`,R.status,JSON.stringify(R.capacity),String(R.concurrency)]))})),E.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,_)=>vt((d)=>{let{purpose:R,backend:h}=_;if(!["application","build","worker","monitoring","backup"].includes(R)||!["server","ecs","asg"].includes(h))throw Error("Unsupported pool purpose or backend.");let r=d.store.createPool({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,purpose:R,backend:h,region:_.region,architecture:_.arch,labels:Z$(_.labels),requiredServerLabels:Z$(_.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...oy(_.capacity)},maxWorkloads:Number(_.max),costWeight:1,concurrency:Number(_.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});Z(`Created ${r.name} (${r.id}).`)})),E.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(T,_)=>vt((d)=>{let R=d.store.listPools(d.controlPlane.project.id).find((r)=>r.id===T||r.name===T),h=new nR(d.controlPlane.store).list(d.controlPlane.project.id).find((r)=>r.id===_||r.name===_);if(!R||!h)throw Error("Pool or server was not found.");d.store.addMember(R.id,h.id),Z(`Attached ${h.name} to ${R.name}.`)})),E.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)=>vt((_)=>{let d=_.service.explain(_.controlPlane.project.id,{purpose:T.purpose,resources:oy(T.resources),region:T.region,architecture:T.arch,labels:Z$(T.labels)});if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],d.map((R)=>[R.poolName,R.serverId??"provider-managed",R.eligible?"yes":"no",JSON.stringify(R.available),`${R.score.fit.toFixed(2)} / ${R.score.spread} / ${R.score.cost}`,R.reasons.join("; ")||"eligible"]))})),E.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(T)=>vt((_)=>{let d=_.store.listPools(_.controlPlane.project.id).find((h)=>h.id===T||h.name===T);if(!d)throw Error("Pool was not found.");let R=_.service.drainPool(d.id);Z(`Draining ${d.name}: moved ${R.moved.length}, blocked ${R.blocked.length} stateful placement(s).`)}))}ME();var Qh=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},pd=(E)=>E==null?void 0:String(E),E5=(E)=>({id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),environmentId:pd(E.environment_id),name:String(E.name),hostname:String(E.hostname),homeRegion:String(E.home_region),regions:Qh(E.regions,[]),trafficPolicy:String(E.traffic_policy),dataPolicy:Qh(E.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(E.status),activeRegion:String(E.active_region),revision:pd(E.revision),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),xX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),region:String(E.region),role:String(E.role),provider:String(E.provider),stackId:pd(E.stack_id),stackRevision:pd(E.stack_revision),status:String(E.status),health:Qh(E.health,{}),lastHealthyAt:pd(E.last_healthy_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),gX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),kind:String(E.kind),sourceRegion:String(E.source_region),targetRegion:String(E.target_region),config:Qh(E.config,{}),status:String(E.status),checkpoint:pd(E.checkpoint),lagSeconds:E.lag_seconds==null?void 0:Number(E.lag_seconds),lastVerifiedAt:pd(E.last_verified_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),bX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),hostname:String(E.hostname),dnsProvider:String(E.dns_provider),cdnEnabled:Number(E.cdn_enabled)===1,wafEnabled:Number(E.waf_enabled)===1,weights:Qh(E.weights,{}),desiredWeights:Qh(E.desired_weights,{}),status:String(E.status),providerState:Qh(E.provider_state,{}),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),T5=(E)=>({id:String(E.id),topologyId:String(E.topology_id),operationId:pd(E.operation_id),kind:String(E.kind),requestedRegion:pd(E.requested_region),revision:pd(E.revision),plan:Qh(E.plan,[]),currentStep:pd(E.current_step),completedSteps:Qh(E.completed_steps,[]),status:String(E.status),error:pd(E.error),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class nt{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}create(E){return this.control.transaction(()=>{if(E.regions.length<2||new Set(E.regions.map((h)=>h.region)).size!==E.regions.length||E.regions.filter((h)=>h.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let T=E.regions.find((h)=>h.role==="primary"),_=this.id(),d=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[_,E.organizationId,E.projectId,E.environmentId??null,E.name,E.hostname,T.region,JSON.stringify(E.regions),E.trafficPolicy,JSON.stringify(E.dataPolicy),T.region,d,d]);for(let h of E.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),_,h.region,h.role,h.provider,d,d]);for(let h of E.dataPolicy.replicate)for(let r of E.regions)for(let N of E.regions.filter((A)=>A.region!==r.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),_,h,r.region,N.region,"{}",d,d]);let R=Object.fromEntries(E.regions.map((h)=>[h.region,h.region===T.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),_,E.hostname,E.dnsProvider??"route53",E.cdnEnabled?1:0,E.wafEnabled?1:0,JSON.stringify(R),JSON.stringify(R),d,d]),this.get(_)})}get(E){let T=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(E);return T?E5(T):void 0}list(E){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(E).map(E5)}targets(E){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(E).map(xX)}channels(E){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(E).map(gX)}route(E){let T=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(E);return T?bX(T):void 0}updateTopology(E,T){let _=this.get(E);if(!_)throw Error("Regional topology was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[d.status,d.activeRegion,d.revision??null,JSON.stringify(d.regions),R,E]),this.get(E)}updateTarget(E,T){let _=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(E);if(!_)throw Error("Regional target was not found.");let d=xX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[R.role,R.stackId??null,R.stackRevision??null,R.status,JSON.stringify(R.health),R.lastHealthyAt??null,h,E]),xX(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(E))}updateChannel(E,T){let _=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(E);if(!_)throw Error("Replication channel was not found.");let d=gX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[R.status,R.checkpoint??null,R.lagSeconds??null,R.lastVerifiedAt??null,h,E]),gX(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(E))}updateRoute(E,T){let _=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(E);if(!_)throw Error("Traffic route was not found.");let d=bX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(R.weights),JSON.stringify(R.desiredWeights),R.status,JSON.stringify(R.providerState),h,E]),bX(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(E))}createExecution(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[T,E.topologyId,E.operationId??null,E.kind,E.requestedRegion??null,E.revision??null,JSON.stringify(E.plan),_,_]),this.execution(T)}execution(E){let T=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(E);return T?T5(T):void 0}executions(E){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(E).map(T5)}updateExecution(E,T){let _=this.execution(E);if(!_)throw Error("Regional execution was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[d.operationId??null,d.currentStep??null,JSON.stringify(d.completedSteps),d.status,d.error??null,R,E]),this.execution(E)}}class lt{store;queue;constructor(E,T){this.store=E;this.queue=T??new nE(E.control)}create(E){return this.store.create(E)}plan(E,T,_){if(!this.store.get(E))throw Error("Regional topology was not found.");let R=this.store.targets(E),h=this.store.channels(E);if(T==="rollout")return[...R.filter((r)=>r.role==="secondary").map((r)=>`apply:${r.region}`),...R.filter((r)=>r.role==="primary").map((r)=>`apply:${r.region}`),...h.map((r)=>`replicate:${r.kind}:${r.targetRegion}`),"traffic:activate"];if(T==="failover"||T==="failback")return[`health:${_}`,`replication:${_}`,`traffic:${_}`,`roles:${_}`];if(T==="destroy")return["traffic:drain",...R.filter((r)=>r.role==="secondary").map((r)=>`delete:${r.region}`),...R.filter((r)=>r.role==="primary").map((r)=>`delete:${r.region}`),"complete"];return["observe","repair"]}enqueue(E){let T=this.store.get(E.topologyId);if(!T)throw Error("Regional topology was not found.");if(["failover","failback"].includes(E.kind)&&(!E.targetRegion||!T.regions.some((h)=>h.region===E.targetRegion)))throw Error("A topology target region is required.");if(E.kind==="failover"&&E.targetRegion===T.activeRegion)throw Error("Target region is already active.");if((E.kind==="destroy"||E.deleteData)&&E.confirmation!==T.name)throw Error("Exact topology name confirmation is required.");if(E.deleteData&&T.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(E.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(E.revision??""))throw Error("An immutable revision is required.");let _=this.plan(T.id,E.kind,E.targetRegion),d=this.store.createExecution({topologyId:T.id,kind:E.kind,requestedRegion:E.targetRegion,revision:E.revision,plan:_}),R=this.queue.enqueue({projectId:T.projectId,environmentId:T.environmentId,kind:`region.${E.kind}`,input:{executionId:d.id,manifest:E.manifest??{},deleteData:E.deleteData===!0},lockKey:`regional-topology:${T.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(d.id,{operationId:R.id}),{execution:this.store.execution(d.id),operation:R}}}var Kb=(E)=>E&&typeof E==="object"&&!Array.isArray(E)?E:{};function _5(E,T){let _=(S)=>{let L=T.find((t)=>t.provider===S.provider);if(!L)throw Error(`No ${S.provider} regional driver is configured.`);return L},d=(S,L,t)=>{S.throwIfCancellationRequested(),S.checkpoint(t,t),E.updateExecution(L.id,{status:"running",currentStep:t,completedSteps:[...E.execution(L.id).completedSteps,t]})},R=async(S,L)=>{let t=E.route(S.id);if(!t)throw Error("Regional traffic route was not found.");let O=E.targets(S.id).find((D)=>D.region===S.activeRegion)??E.targets(S.id)[0];if(!O)throw Error("Regional traffic target was not found.");E.updateRoute(t.id,{status:"applying",desiredWeights:L});let U=await _(O).applyTraffic({route:E.route(S.id),topology:S,weights:L});E.updateRoute(t.id,{status:Object.values(L).every((D)=>D===0)?"drained":"in_sync",weights:L,providerState:U.providerState})},h=async(S,L,t,O)=>{E.updateTopology(t.id,{status:"provisioning"});let U=L.revision,D=O.manifest??{},C=E.targets(t.id).sort((c,z)=>Number(c.role==="primary")-Number(z.role==="primary"));for(let c of C){d(S,L,`apply:${c.region}`),E.updateTarget(c.id,{status:"provisioning"});let z=await _(c).applyStack({target:c,revision:U,manifest:D,signal:S.signal}),j=await _(c).health({target:E.updateTarget(c.id,{stackId:z.stackId,stackRevision:U})});if(!j.healthy)throw Error(`Regional health gate failed in ${c.region}.`);E.updateTarget(c.id,{status:"ready",health:j.evidence,lastHealthyAt:new Date().toISOString()})}for(let c of E.channels(t.id)){d(S,L,`replicate:${c.kind}:${c.targetRegion}`),E.updateChannel(c.id,{status:"configuring"});let z=C.find((G)=>G.region===c.sourceRegion),j=await _(z).configureReplication({channel:c,topology:t}),W=await _(z).verifyReplication({channel:E.updateChannel(c.id,{checkpoint:j.checkpoint,lagSeconds:j.lagSeconds}),topology:t});if(!W.healthy||W.lagSeconds>t.dataPolicy.maxLagSeconds)throw Error(`${c.kind} replication to ${c.targetRegion} exceeds the RPO.`);E.updateChannel(c.id,{status:"in_sync",checkpoint:W.checkpoint,lagSeconds:W.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(S,L,"traffic:activate");let w=Object.fromEntries(t.regions.map((c)=>[c.region,c.region===t.activeRegion?100:0]));return await R(t,w),E.updateTopology(t.id,{status:"ready",revision:U}),{revision:U,activeRegion:t.activeRegion}},r=async(S,L,t)=>{let O=L.requestedRegion,U=E.targets(t.id).find((w)=>w.region===O);if(!U)throw Error("Requested regional target was not found.");E.updateTopology(t.id,{status:L.kind==="failover"?"failing_over":"failing_back"}),d(S,L,`health:${O}`);let D=await _(U).health({target:U});if(!D.healthy)throw Error(`Target region ${O} is unhealthy.`);E.updateTarget(U.id,{status:"ready",health:D.evidence,lastHealthyAt:new Date().toISOString()}),d(S,L,`replication:${O}`);for(let w of E.channels(t.id).filter((c)=>c.targetRegion===O)){let c=await _(U).verifyReplication({channel:w,topology:t});if(!c.healthy||c.lagSeconds>t.dataPolicy.maxLagSeconds)throw Error(`${w.kind} replication is outside the failover RPO.`);E.updateChannel(w.id,{status:"in_sync",checkpoint:c.checkpoint,lagSeconds:c.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(S,L,`traffic:${O}`),await R(t,Object.fromEntries(t.regions.map((w)=>[w.region,w.region===O?100:0]))),d(S,L,`roles:${O}`);let C=t.regions.map((w)=>({...w,role:w.region===O?"primary":"secondary"}));for(let w of E.targets(t.id))E.updateTarget(w.id,{role:w.region===O?"primary":"secondary"});return E.updateTopology(t.id,{status:L.kind==="failover"?"failed_over":"ready",activeRegion:O,regions:C}),{activeRegion:O}},N=async(S,L,t,O)=>{E.updateTopology(t.id,{status:"destroying"}),d(S,L,"traffic:drain"),await R(t,Object.fromEntries(t.regions.map((D)=>[D.region,0])));let U=O.deleteData!==!0;for(let D of E.targets(t.id).sort((C,w)=>Number(C.role==="primary")-Number(w.role==="primary")))d(S,L,`delete:${D.region}`),E.updateTarget(D.id,{status:"deleting"}),await _(D).deleteStack({target:D,retainData:U,signal:S.signal}),E.updateTarget(D.id,{status:"deleted"});return d(S,L,"complete"),E.updateTopology(t.id,{status:"destroyed"}),{destroyed:!0,dataRetained:U}},A=async(S)=>{let L=Kb(S.operation.input),t=E.execution(String(L.executionId??""));if(!t)throw Error("Regional execution was not found.");let O=E.get(t.topologyId);if(!O)throw Error("Regional topology was not found.");try{let U;if(t.kind==="rollout")U=await h(S,t,O,L);else if(t.kind==="failover"||t.kind==="failback")U=await r(S,t,O);else if(t.kind==="destroy")U=await N(S,t,O,L);else throw Error("Regional reconciliation is not configured.");return E.updateExecution(t.id,{status:"succeeded",currentStep:void 0}),{executionId:t.id,...U}}catch(U){if(E.updateExecution(t.id,{status:S.cancellationRequested()?"cancelled":"failed",error:U instanceof Error?U.message:String(U)}),E.get(O.id)?.status!=="destroyed")E.updateTopology(O.id,{status:"failed"});throw U}};return{"region.rollout":A,"region.failover":A,"region.failback":A,"region.destroy":A,"region.reconcile":A}}class kX{provider;reason;constructor(E,T="Configure a regional provider transport before executing this operation."){this.provider=E;this.reason=T}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}async function fb(){let E=await o(),T=lE(process.cwd(),E),_=new nt(T.store),d=new lt(_);return{controlPlane:T,store:_,service:d}}async function qN(E){let T=await fb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}var it=(E,T)=>{let _=E.store.list(E.controlPlane.project.id).find((d)=>d.id===T||d.name===T);if(!_)throw Error("Regional topology was not found.");return _},Pb=(E)=>E.split(",").map((T,_)=>{let[d,R="aws"]=T.split(":");return{region:String(d),provider:R,role:_===0?"primary":"secondary"}}),Zb=(E)=>{let T=new Set(["s3","dynamodb","secrets"]),_=E.split(",").map((R)=>R.trim()),d=_.find((R)=>!T.has(R));if(d)throw Error(`Unsupported replication kind: ${d}`);return _};function uX(E){E.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(T)=>qN((_)=>{let d=_.store.list(_.controlPlane.project.id).map((R)=>({topology:R,targets:_.store.targets(R.id),channels:_.store.channels(R.id),route:_.store.route(R.id),executions:_.store.executions(R.id)}));if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Hostname","Active","Status","Revision","Replication"],d.map((R)=>[R.topology.name,R.topology.hostname,R.topology.activeRegion,R.topology.status,R.topology.revision??"—",`${R.channels.filter((h)=>h.status==="in_sync").length}/${R.channels.length} in sync`]))})),E.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,_)=>qN((d)=>{if(!_.hostname||!_.regions)throw Error("--hostname and --regions are required.");let R=d.service.create({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,hostname:_.hostname,regions:Pb(_.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Zb(String(_.replicate)),maxLagSeconds:Number(_.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!_.cdn,wafEnabled:!!_.waf});Z(`Created ${R.name} (${R.id}); run region:rollout with an immutable manifest.`)})),E.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(T,_,d)=>qN((R)=>EE(["Step"],R.service.plan(it(R,T).id,_,d.target).map((h)=>[h])))),E.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(T,_,d)=>qN(async(R)=>{let h=d.manifest?await Bun.file(d.manifest).json():{},r=R.service.enqueue({topologyId:it(R,T).id,kind:"rollout",revision:_,manifest:h});Z(`Regional rollout queued: ${r.operation.id}`)})),E.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"failover",targetRegion:_});Z(`Failover queued: ${R.operation.id}`)})),E.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"failback",targetRegion:_});Z(`Failback queued: ${R.operation.id}`)})),E.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"destroy",confirmation:_.confirm});Z(`Regional teardown queued: ${R.operation.id}; replicated data remains retained.`)}))}ME();var mt="0.7.73";import{createHash as vX,createPublicKey as h5,verify as xb}from"node:crypto";function at(E){if(E===null||typeof E!=="object")return JSON.stringify(E);if(Array.isArray(E))return`[${E.map(at).join(",")}]`;return`{${Object.keys(E).sort().map((T)=>`${JSON.stringify(T)}:${at(E[T])}`).join(",")}}`}var r5=(E)=>vX("sha256").update(at(E)).digest("hex"),q$=(E)=>vX("sha256").update(at(E)).digest("hex"),N5=(E)=>vX("sha256").update(h5(E).export({type:"spki",format:"der"})).digest("hex");function A5(E,T,_){try{return xb(null,Buffer.from(at(E)),h5(_),Buffer.from(T,"base64"))}catch{return!1}}var d5=(E)=>E.replace(/^v/,"").split(/[.-]/).slice(0,3).map((T)=>Number(T)||0),R5=(E,T)=>{let _=d5(E),d=d5(T);for(let R=0;R<3;R++){let h=(_[R]??0)-(d[R]??0);if(h)return h}return 0};function S5(E,T){let _=[];if(T.schemaVersion<E.minimumSchema)_.push(`schema ${T.schemaVersion} is below ${E.minimumSchema}`);if(T.schemaVersion>E.maximumSchema)_.push(`schema ${T.schemaVersion} is above ${E.maximumSchema}`);if(E.minimumVersion&&R5(T.currentVersion,E.minimumVersion)<0)_.push(`platform ${T.currentVersion} is below ${E.minimumVersion}`);if(R5(E.version,T.currentVersion)<=0)_.push(`version ${E.version} is not newer than ${T.currentVersion}`);if(!E.artifacts.some((d)=>d.platform===T.platform&&d.architecture===T.architecture))_.push(`no artifact for ${T.platform}/${T.architecture}`);return{compatible:_.length===0,reasons:_}}var Mh=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},F_=(E)=>E==null?void 0:String(E),gb=(E)=>({id:String(E.id),organizationId:String(E.organization_id),name:String(E.name),algorithm:"ed25519",publicKeyPem:String(E.public_key_pem),fingerprint:String(E.fingerprint),revokedAt:F_(E.revoked_at),createdAt:String(E.created_at)}),L5=(E)=>({id:String(E.id),organizationId:String(E.organization_id),version:String(E.version),channel:String(E.channel),publishedAt:String(E.published_at),keyId:String(E.key_id),digest:String(E.digest),document:Mh(E.document,{}),signature:String(E.signature),verificationStatus:String(E.verification_status),compatibility:Mh(E.compatibility,{compatible:!1,reasons:[]}),createdAt:String(E.created_at)}),t5=(E)=>({id:String(E.id),projectId:String(E.project_id),name:String(E.name),schedule:String(E.schedule),timezone:String(E.timezone),durationMinutes:Number(E.duration_minutes),allowedOperations:Mh(E.allowed_operations,[]),requireApproval:Number(E.require_approval)===1,enabled:Number(E.enabled)===1,createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),O5=(E)=>({id:String(E.id),projectId:String(E.project_id),manifestId:String(E.manifest_id),windowId:F_(E.window_id),fromVersion:String(E.from_version),strategy:String(E.strategy),batchSize:Number(E.batch_size),healthGate:Mh(E.health_gate,{}),status:String(E.status),currentStage:F_(E.current_stage),backupId:F_(E.backup_id),approvedBy:F_(E.approved_by),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),nX=(E)=>({id:String(E.id),campaignId:String(E.campaign_id),serverId:F_(E.server_id),target:String(E.target),cohort:Number(E.cohort),previousVersion:String(E.previous_version),status:String(E.status),evidence:Mh(E.evidence,{}),error:F_(E.error),startedAt:F_(E.started_at),finishedAt:F_(E.finished_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),U5=(E)=>({id:String(E.id),projectId:String(E.project_id),kind:String(E.kind),criteria:Mh(E.criteria,{}),candidates:Mh(E.candidates,[]),candidateDigest:String(E.candidate_digest),estimatedBytes:Number(E.estimated_bytes),status:String(E.status),confirmation:F_(E.confirmation),expiresAt:String(E.expires_at),result:Mh(E.result,{}),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),$5=(E)=>({id:String(E.id),projectId:String(E.project_id),backupPolicyId:F_(E.backup_policy_id),recoveryPointId:F_(E.recovery_point_id),topologyId:F_(E.topology_id),scenario:String(E.scenario),isolatedTarget:String(E.isolated_target),expectedRpoMinutes:Number(E.expected_rpo_minutes),expectedRtoMinutes:Number(E.expected_rto_minutes),status:String(E.status),operationId:F_(E.operation_id),evidence:Mh(E.evidence,{}),measuredRpoMinutes:E.measured_rpo_minutes==null?void 0:Number(E.measured_rpo_minutes),measuredRtoMinutes:E.measured_rto_minutes==null?void 0:Number(E.measured_rto_minutes),cleanupVerified:Number(E.cleanup_verified)===1,error:F_(E.error),startedAt:F_(E.started_at),finishedAt:F_(E.finished_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class st{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}addTrustedKey(E){let T=this.id(),_=this.now().toISOString(),d=N5(E.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[T,E.organizationId,E.name,E.publicKeyPem,d,_]),this.key(T)}key(E){let T=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(E);return T?gb(T):void 0}revokeKey(E){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),E]),this.key(E)}importManifest(E){let T=this.key(E.keyId);if(!T||T.organizationId!==E.organizationId)throw Error("Trusted update key was not found.");if(T.revokedAt)throw Error("Update signing key is revoked.");if(!A5(E.document,E.signature,T.publicKeyPem))throw Error("Update manifest signature is invalid.");let _=S5(E.document,E.current),d=r5(E.document),R=this.id(),h=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[R,E.organizationId,E.document.version,E.document.channel,new Date(E.document.publishedAt).toISOString(),E.keyId,d,JSON.stringify(E.document),E.signature,JSON.stringify(_),h]),this.manifest(R)}manifest(E){let T=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(E);return T?L5(T):void 0}manifests(E){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(E).map(L5)}createWindow(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[T,E.projectId,E.name,E.schedule,E.timezone,E.durationMinutes,JSON.stringify(E.allowedOperations),E.requireApproval===!1?0:1,_,_]),this.window(T)}window(E){let T=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(E);return T?t5(T):void 0}windows(E){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(E).map(t5)}createCampaign(E){return this.control.transaction(()=>{let T=this.manifest(E.manifestId);if(!T?.compatibility.compatible||T.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!E.backupId)throw Error("A verified pre-upgrade backup is required.");let _=this.id(),d=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[_,E.projectId,E.manifestId,E.windowId??null,E.fromVersion,E.strategy,E.batchSize,JSON.stringify(E.healthGate),E.backupId,E.approvedBy??null,d,d]),E.targets.forEach((R,h)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),_,R.serverId??null,R.target,E.strategy==="canary"?h===0?0:1+Math.floor((h-1)/E.batchSize):Math.floor(h/E.batchSize),R.previousVersion,d,d])),this.campaign(_)})}campaign(E){let T=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(E);return T?O5(T):void 0}campaigns(E){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(E).map(O5)}targets(E){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(E).map(nX)}updateCampaign(E,T){let _=this.campaign(E);if(!_)throw Error("Upgrade campaign was not found.");let d={..._,...T};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[d.status,d.currentStage??null,this.now().toISOString(),E]),this.campaign(E)}updateTarget(E,T){let _=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(E);if(!_)throw Error("Upgrade target was not found.");let d={...nX(_),...T};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.evidence),d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),E]),nX(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(E))}createCleanup(E){let T=[...E.candidates].sort((r,N)=>r.id.localeCompare(N.id)),_=q$(T),d=this.id(),R=this.now().toISOString(),h=new Date(this.now().getTime()+(E.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[d,E.projectId,E.kind,JSON.stringify(E.criteria),JSON.stringify(T),_,T.reduce((r,N)=>r+N.bytes,0),h,R,R]),this.cleanup(d)}cleanup(E){let T=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(E);return T?U5(T):void 0}cleanups(E){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(E).map(U5)}updateCleanup(E,T){let _=this.cleanup(E);if(!_)throw Error("Cleanup plan was not found.");let d={..._,...T};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[d.status,d.confirmation??null,JSON.stringify(d.result),this.now().toISOString(),E]),this.cleanup(E)}createDrill(E){if(!/^isolated:\/\//.test(E.isolatedTarget))throw Error("DR drills require an isolated target.");let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[T,E.projectId,E.backupPolicyId??null,E.recoveryPointId??null,E.topologyId??null,E.scenario,E.isolatedTarget,E.expectedRpoMinutes,E.expectedRtoMinutes,_,_]),this.drill(T)}drill(E){let T=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(E);return T?$5(T):void 0}drills(E){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(E).map($5)}updateDrill(E,T){let _=this.drill(E);if(!_)throw Error("DR drill was not found.");let d={..._,...T};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,JSON.stringify(d.evidence),d.measuredRpoMinutes??null,d.measuredRtoMinutes??null,d.cleanupVerified?1:0,d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),E]),this.drill(E)}}function bb(E,T=new Date){if(!E.enabled)return!1;let _=new Date(E.schedule);if(!Number.isNaN(_.getTime()))return T>=_&&T.getTime()<=_.getTime()+E.durationMinutes*60000;let d=/^(\d{2}):(\d{2})$/.exec(E.schedule);if(!d)return!1;let R=new Intl.DateTimeFormat("en-US",{timeZone:E.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(T),h=Number(R.find((N)=>N.type==="hour")?.value)*60+Number(R.find((N)=>N.type==="minute")?.value),r=Number(d[1])*60+Number(d[2]);return h>=r&&h<r+E.durationMinutes}class pt{store;now;queue;constructor(E,T,_=()=>new Date){this.store=E;this.now=_;this.queue=T??new nE(E.control)}enqueueCampaign(E,T={}){let _=this.store.campaign(E);if(!_)throw Error("Upgrade campaign was not found.");let d=_.windowId?this.store.window(_.windowId):void 0;if(d&&!d.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(d&&!T.overrideWindow&&!bb(d,this.now()))throw Error("Upgrade is outside its maintenance window.");if(d?.requireApproval&&!T.approvedBy&&!_.approvedBy)throw Error("Maintenance approval is required.");let R=this.queue.enqueue({projectId:_.projectId,actorId:T.approvedBy,kind:"maintenance.upgrade",input:{campaignId:E},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(E,{status:"queued"}),operation:R}}async previewCleanup(E,T){let _=T.find((d)=>d.kind===E.kind);if(!_)throw Error(`No ${E.kind} cleanup driver is configured.`);return this.store.createCleanup({...E,candidates:await _.discover(E.criteria)})}enqueueCleanup(E,T){let _=this.store.cleanup(E);if(!_||_.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(_.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let d=`DELETE ${_.candidates.length} ${_.kind}`;if(T!==d)throw Error(`Exact confirmation ${d} is required.`);let R=this.queue.enqueue({projectId:_.projectId,kind:"maintenance.cleanup",input:{planId:E},lockKey:`cleanup:${_.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(E,{status:"approved",confirmation:T}),operation:R}}enqueueDrill(E){let T=this.store.drill(E);if(!T||T.status!=="planned")throw Error("A planned DR drill is required.");let _=this.queue.enqueue({projectId:T.projectId,kind:"maintenance.drill",input:{drillId:E},lockKey:`drill:${T.scenario}:${T.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(E,{status:"queued",operationId:_.id}),operation:_}}}var lX=(E)=>E&&typeof E==="object"&&!Array.isArray(E)?E:{};function D5(E){return{"maintenance.upgrade":async(R)=>{let h=E.store.campaign(String(lX(R.operation.input).campaignId??""));if(!h||!E.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let r=E.store.manifest(h.manifestId);if(!r?.compatibility.compatible||r.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let N=r.document.artifacts.find((S)=>S.platform===process.platform&&S.architecture===process.arch)??r.document.artifacts[0];if(!N)throw Error("No update artifact matches this platform.");E.store.updateCampaign(h.id,{status:"running",currentStage:"preflight"});let A=[];try{for(let S of[...new Set(E.store.targets(h.id).map((L)=>L.cohort))].sort((L,t)=>L-t)){E.store.updateCampaign(h.id,{currentStage:`cohort:${S}`});for(let L of E.store.targets(h.id).filter((t)=>t.cohort===S)){R.throwIfCancellationRequested(),R.checkpoint(`download:${L.target}`,"Downloading signed platform artifact."),E.store.updateTarget(L.id,{status:"downloading",startedAt:new Date().toISOString()});let t=await E.platform.download({target:L,artifact:N,signal:R.signal});if(t.sha256!==N.sha256)throw Error(`Artifact checksum mismatch for ${L.target}.`);R.checkpoint(`install:${L.target}`,"Installing verified artifact."),E.store.updateTarget(L.id,{status:"installing"}),await E.platform.install({target:L,path:t.path,version:r.version,signal:R.signal}),A.push(L);let O=await E.platform.health({target:L,gate:h.healthGate});if(!O.healthy)throw Error(`Upgrade health gate failed for ${L.target}.`);E.store.updateTarget(L.id,{status:"healthy",evidence:O.evidence,finishedAt:new Date().toISOString()})}}return E.store.updateCampaign(h.id,{status:"succeeded",currentStage:void 0}),{campaignId:h.id,version:r.version,targets:A.length}}catch(S){E.store.updateCampaign(h.id,{status:"rolling_back",currentStage:"rollback"});for(let L of A.reverse())E.store.updateTarget(L.id,{status:"rolling_back"}),await E.platform.rollback({target:L,version:L.previousVersion,signal:R.signal}),E.store.updateTarget(L.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw E.store.updateCampaign(h.id,{status:"rolled_back",currentStage:void 0}),S}},"maintenance.cleanup":async(R)=>{let h=E.store.cleanup(String(lX(R.operation.input).planId??""));if(!h||h.status!=="approved")throw Error("Approved cleanup plan was not found.");if(q$([...h.candidates].sort((L,t)=>L.id.localeCompare(t.id)))!==h.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let r=E.cleanup?.find((L)=>L.kind===h.kind);if(!r)throw Error(`No ${h.kind} cleanup driver is configured.`);E.store.updateCleanup(h.id,{status:"running"});let N=[],A=[];for(let L of h.candidates){R.throwIfCancellationRequested();try{await r.remove(L),N.push(L.id)}catch(t){A.push({id:L.id,error:t instanceof Error?t.message:String(t)})}}let S=A.length?N.length?"partial":"failed":"succeeded";if(E.store.updateCleanup(h.id,{status:S,result:{removed:N,failed:A,reclaimedBytes:h.candidates.filter((L)=>N.includes(L.id)).reduce((L,t)=>L+t.bytes,0)}}),A.length)throw Error(`Cleanup failed for ${A.length} candidate(s).`);return{planId:h.id,removed:N.length,reclaimedBytes:h.estimatedBytes}},"maintenance.drill":async(R)=>{let h=E.store.drill(String(lX(R.operation.input).drillId??""));if(!h)throw Error("DR drill was not found.");let r=E.recovery?.find((t)=>t.scenario===h.scenario);if(!r)throw Error(`No ${h.scenario} recovery driver is configured.`);let N=new Date;E.store.updateDrill(h.id,{status:"restoring",startedAt:N.toISOString()});let A=h.isolatedTarget,S={},L={};try{R.checkpoint("restore","Restoring into isolated drill target.");let t=await r.restore({drill:h,signal:R.signal});if(!t.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");A=t.target,S=t.evidence;let O=(N.getTime()-new Date(t.recoveryPointAt).getTime())/60000;E.store.updateDrill(h.id,{status:"verifying",measuredRpoMinutes:O,evidence:{restore:S}}),R.checkpoint("verify","Running recovery health checks without production traffic.");let U=await r.verify({drill:h,target:A});L=U.evidence;let D=(Date.now()-N.getTime())/60000;if(!U.healthy||O>h.expectedRpoMinutes||D>h.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");E.store.updateDrill(h.id,{measuredRpoMinutes:O,measuredRtoMinutes:D,evidence:{restore:S,verify:L}})}catch(t){throw E.store.updateDrill(h.id,{status:"failed",error:t instanceof Error?t.message:String(t),evidence:{restore:S,verify:L}}),t}finally{E.store.updateDrill(h.id,{status:"cleaning"});try{await r.cleanup({drill:h,target:A});let t=E.store.drill(h.id);E.store.updateDrill(h.id,{status:t.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(t){E.store.updateDrill(h.id,{status:"cleanup_required",cleanupVerified:!1,error:t instanceof Error?t.message:String(t),finishedAt:new Date().toISOString()})}}return{drillId:h.id,status:E.store.drill(h.id).status}}}}var I5={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class ot{kind;control;projectId;organizationId;constructor(E,T,_,d){this.kind=E;this.control=T;this.projectId=_;this.organizationId=d}async discover(E){let T=Math.max(1,Math.min(3650,Number(E.olderThanDays??30))),_=new Date(Date.now()-T*86400000).toISOString(),d=I5[this.kind],R=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(d.select).all(R,_).map((r)=>({id:String(r.id),kind:this.kind,label:`${this.kind}:${String(r.id)}`,bytes:Number(r.bytes??0),metadata:{createdAt:String(r.created_at)}}))}async remove(E){if(this.control.database.run(I5[this.kind].remove,[E.id]).changes!==1)throw Error(`${E.label} changed or is no longer removable.`)}}async function kb(){let E=await o(),T=lE(process.cwd(),E),_=new st(T.store),d=new pt(_),R=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((h)=>new ot(h,T.store,T.project.id,T.organization.id));return{controlPlane:T,store:_,service:d,cleanup:R}}async function Vh(E){let T=await kb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}function iX(E){E.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(T)=>Vh((_)=>{let d={manifests:_.store.manifests(_.controlPlane.organization.id),windows:_.store.windows(_.controlPlane.project.id),campaigns:_.store.campaigns(_.controlPlane.project.id),cleanups:_.store.cleanups(_.controlPlane.project.id),drills:_.store.drills(_.controlPlane.project.id)},R=[...d.manifests.map((h)=>["update",h.version,h.compatibility.compatible?"compatible":"blocked",h.compatibility.reasons.join("; ")||h.channel]),...d.campaigns.map((h)=>["upgrade",h.id,h.status,h.currentStage??h.fromVersion]),...d.cleanups.map((h)=>["cleanup",h.kind,h.status,`${h.candidates.length} items / ${h.estimatedBytes} bytes`]),...d.drills.map((h)=>["DR drill",h.scenario,h.status,h.isolatedTarget])];if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Area","Name / version","Status","Detail"],R)})),E.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(T,_)=>Vh(async(d)=>{let R=d.store.addTrustedKey({organizationId:d.controlPlane.organization.id,name:T,publicKeyPem:await Bun.file(_).text()});Z(`Trusted ${R.name}: ${R.fingerprint}`)})),E.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(T,_,d)=>Vh(async(R)=>{let h=await Bun.file(T).json(),r=(await Bun.file(_).text()).trim(),N=R.store.importManifest({organizationId:R.controlPlane.organization.id,keyId:d,document:h,signature:r,current:{schemaVersion:R.controlPlane.store.health().schemaVersion,currentVersion:mt,platform:process.platform,architecture:process.arch}});Z(`Verified ${N.version}; ${N.compatibility.compatible?"compatible":"blocked: "+N.compatibility.reasons.join("; ")}`)})),E.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,_,d)=>Vh((R)=>{let h=R.store.createWindow({projectId:R.controlPlane.project.id,name:T,schedule:_,timezone:d.timezone,durationMinutes:Number(d.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});Z(`Created ${h.name} (${h.id}).`)})),E.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,_,d)=>Vh((R)=>{let h=new nR(R.controlPlane.store).list(R.controlPlane.project.id).filter((A)=>A.status==="ready").map((A)=>({serverId:A.id,target:A.name,previousVersion:A.bootstrapVersion??mt}));if(!h.length)h.push({target:"control-plane",previousVersion:mt});let r=R.store.createCampaign({projectId:R.controlPlane.project.id,manifestId:T,fromVersion:mt,strategy:d.strategy==="rolling"?"rolling":"canary",batchSize:Number(d.batch),healthGate:{kind:"platform"},backupId:_,targets:h}),N=R.service.enqueueCampaign(r.id);Z(`Staged upgrade queued: ${N.operation.id}`)})),E.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(T,_)=>Vh(async(d)=>{let R=await d.service.previewCleanup({projectId:d.controlPlane.project.id,kind:T,criteria:{olderThanDays:Number(_.olderThan)}},d.cleanup);EE(["ID","Candidate","Bytes"],R.candidates.map((h)=>[h.id,h.label,String(h.bytes)])),$(`Apply with: cloud cleanup:apply ${R.id} --confirm "DELETE ${R.candidates.length} ${R.kind}"`)})),E.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(T,_)=>Vh((d)=>{let R=d.service.enqueueCleanup(T,String(_.confirm??""));Z(`Cleanup queued: ${R.operation.id}`)})),E.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,_,d)=>Vh((R)=>{let h=R.store.createDrill({projectId:R.controlPlane.project.id,scenario:T,isolatedTarget:_,expectedRpoMinutes:Number(d.rpo),expectedRtoMinutes:Number(d.rto),recoveryPointId:d.recoveryPoint,topologyId:d.topology});Z(`Planned isolated drill ${h.id}.`)})),E.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(T)=>Vh((_)=>{let d=_.service.enqueueDrill(T);Z(`DR drill queued: ${d.operation.id}`)}))}ME();xr();Bd();async function mX(){try{return(await o()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function aX(E){E.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(T)=>{b("Lambda Functions");let _=T?.region||await mX(),d=new jT(_);try{let{Functions:R=[]}=await d.listFunctions({MaxItems:50});if(!R.length){$("No functions found");return}EE(["Name","Runtime","Memory","Timeout","Last Modified"],R.map((h)=>[h.FunctionName??"-",h.Runtime??"-",h.MemorySize?`${h.MemorySize} MB`:"-",h.Timeout?`${h.Timeout}s`:"-",h.LastModified??"-"]))}catch(R){Q(`Failed to list functions: ${R.message}`),process.exitCode=1}}),E.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,_)=>{b(`Invoking ${T}`);let d=_?.region||await mX(),R=new jT(d),h=new n("Invoking function...");h.start();try{let r=await R.invoke({FunctionName:T,InvocationType:_?.async?"Event":"RequestResponse",Payload:_?.payload||"{}",LogType:_?.async?"None":"Tail"});if(r.FunctionError){if(h.fail(`Function returned an error (${r.FunctionError})`),r.Payload)$(r.Payload);process.exitCode=1;return}if(h.succeed(`Invoked (status ${r.StatusCode})`),r.Payload)$(`
9612
+ `).find((R)=>R&&!R.startsWith("#"))?.trim().split(/\s+/);if(_.code!==0||!d?.[1]||!d[2])throw Error(`SSH host-key scan failed: ${_.stderr.trim()||"no key returned"}`);return{algorithm:d[1],key:d[2]}}async exec(E,T){if(E.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return vy(["ssh","-p",String(E.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${E.sshUser}@${E.endpoint}`,T])}}var Jb=(E)=>`SHA256:${Xb("sha256").update(Buffer.from(E,"base64")).digest("base64").replace(/=+$/,"")}`,Fb=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class eh{provider;transport;discoverer;constructor(E,T=new ny,_){this.provider=E;this.transport=T;this.discoverer=_}discover(E){return this.discoverer?.(E)??Promise.resolve([])}async test(E){try{let T=await this.transport.scan(E.endpoint,E.sshPort);return{reachable:!0,hostKeyAlgorithm:T.algorithm,hostKeyFingerprint:Jb(T.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(E){let T=await this.transport.exec(E,Fb);if(T.code!==0)throw Error(`Fleet validation failed: ${T.stderr.trim()||T.code}`);try{return JSON.parse(T.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(E,T){let _=await this.transport.exec(E,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${T.length}`);if(_.code!==0)throw Error(`Fleet bootstrap failed: ${_.stderr.trim()||_.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function ly(E,T){return{"fleet.bootstrap":async(_)=>{let d=_.operation.input&&typeof _.operation.input==="object"&&!Array.isArray(_.operation.input)?_.operation.input:{},R=E.get(String(d.serverId??""));if(!R)throw Error("Queued fleet server was not found.");let h=T.find((A)=>A.provider===R.provider);if(!h)throw Error(`No ${R.provider} fleet driver is configured.`);let r=Array.isArray(d.steps)?d.steps.map(String):[];if(_.checkpoint("preflight","Rechecking pinned trust and healthy validation."),R.trustState!=="pinned"||!R.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");_.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let N=await h.bootstrap(R,r);return E.update(R.id,{bootstrapVersion:N.version,status:"ready"}),_.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:R.id,bootstrapVersion:N.version,steps:r.length}}}}var vR=(E)=>E==null?void 0:String(E),PN=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},fX=(E)=>({id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),resourceId:String(E.resource_id),name:String(E.name),provider:String(E.provider),providerId:vR(E.provider_id),region:vR(E.region),zone:vR(E.zone),endpoint:String(E.endpoint),sshUser:String(E.ssh_user),sshPort:Number(E.ssh_port),credentialRef:String(E.credential_ref),hostKeyAlgorithm:vR(E.host_key_algorithm),hostKeyFingerprint:vR(E.host_key_fingerprint),pendingHostKey:vR(E.pending_host_key),roles:PN(E.roles,[]),labels:PN(E.labels,{}),taints:PN(E.taints,[]),capacity:PN(E.capacity,{}),usage:PN(E.usage,{}),capabilities:PN(E.capabilities,{}),status:String(E.status),trustState:String(E.trust_state),validation:PN(E.validation,void 0),bootstrapVersion:vR(E.bootstrap_version),heartbeatAt:vR(E.heartbeat_at),lastSeenAt:vR(E.last_seen_at),archivedAt:vR(E.archived_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class nR{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}get(E){let T=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(E);return T?fX(T):void 0}list(E,T=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(E).map(fX).filter((_)=>T||_.status!=="archived")}findProvider(E,T,_){let d=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(E,T,_);return d?fX(d):void 0}create(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[T,E.organizationId,E.projectId,E.resourceId,E.name,E.provider,E.providerId??null,E.region??null,E.zone??null,E.endpoint,E.sshUser,E.sshPort,E.credentialRef,E.hostKeyAlgorithm??null,E.hostKeyFingerprint??null,E.pendingHostKey??null,JSON.stringify(E.roles),JSON.stringify(E.labels),JSON.stringify(E.taints),JSON.stringify(E.capacity),JSON.stringify(E.usage),JSON.stringify(E.capabilities),E.status,E.trustState,JSON.stringify(E.validation??{}),E.bootstrapVersion??null,E.heartbeatAt??null,E.lastSeenAt??null,E.archivedAt??null,_,_]),this.get(T)}update(E,T){let _=this.get(E);if(!_)throw Error("Server was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[d.name,d.providerId??null,d.region??null,d.zone??null,d.endpoint,d.sshUser,d.sshPort,d.credentialRef,d.hostKeyAlgorithm??null,d.hostKeyFingerprint??null,d.pendingHostKey??null,JSON.stringify(d.roles),JSON.stringify(d.labels),JSON.stringify(d.taints),JSON.stringify(d.capacity),JSON.stringify(d.usage),JSON.stringify(d.capabilities),d.status,d.trustState,JSON.stringify(d.validation??{}),d.bootstrapVersion??null,d.heartbeatAt??null,d.lastSeenAt??null,d.archivedAt??null,R,E]),this.get(E)}}var zb=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class gt{store;drivers;now;queue;constructor(E,T,_,d=()=>new Date){this.store=E;this.drivers=T;this.now=d;this.queue=_??new nE(E.control)}driver(E){let T=this.drivers.find((_)=>_.provider===E);if(!T)throw Error(`No ${E} fleet driver is configured.`);return T}enroll(E){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(E.name))throw Error("Server name is invalid.");if(!zb.test(E.endpoint)||E.sshUser==="root"||!E.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let T=E.providerId?this.store.findProvider(E.organizationId,E.provider,E.providerId):void 0;if(T)return this.store.update(T.id,{endpoint:E.endpoint,region:E.region,zone:E.zone});let _=this.store.control.createResource({projectId:E.projectId,kind:"server",slug:E.name,name:E.name,provider:E.provider,providerId:E.providerId}),d=this.driver(E.provider);return this.store.create({...E,resourceId:_.id,sshPort:E.sshPort??22,labels:E.labels??{},taints:[],capacity:{},usage:{},capabilities:d.capabilities(),status:"pending",trustState:"unverified"})}async test(E){let T=this.store.get(E);if(!T)throw Error("Server was not found.");let _=await this.driver(T.provider).test(T);if(!_.reachable)return this.store.update(E,{status:"unreachable"});if(T.hostKeyFingerprint&&T.hostKeyFingerprint!==_.hostKeyFingerprint)return this.store.update(E,{status:"degraded",trustState:"rotation_pending",pendingHostKey:_.hostKeyFingerprint});return this.store.update(E,{hostKeyAlgorithm:_.hostKeyAlgorithm,hostKeyFingerprint:_.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(E,T){let _=this.store.get(E);if(!_||_.pendingHostKey!==T)throw Error("Pending host key does not match.");return this.store.update(E,{hostKeyFingerprint:T,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(E){let T=this.store.get(E);if(!T||T.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let _=await this.driver(T.provider).validate(T),d=[];if(!["x64","arm64","x86_64","aarch64"].includes(_.arch??""))d.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let r of["curl","tar"])if(!_.tools?.[r])d.push({code:`tool.${r}`,severity:"error",message:`${r} is missing.`,remediation:`Install ${r} before bootstrap.`});if(Math.abs(_.timeSkewSeconds??0)>60)d.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!_.dnsOk)d.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let R={valid:!d.some((r)=>r.severity==="error"),facts:_,findings:d,validatedAt:this.now().toISOString(),validatorVersion:"1"},h={cpu:_.cpuCores??0,memoryBytes:_.memoryBytes??0,diskBytes:_.diskBytes??0};return this.store.update(E,{validation:R,capacity:h,status:R.valid?"ready":"degraded"})}bootstrap(E,T=!1){let _=this.store.get(E);if(!_?.validation?.valid)throw Error("A healthy validation report is required.");let d=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!T)return{preview:!0,steps:d};let R=this.queue.enqueue({projectId:_.projectId,resourceId:_.resourceId,kind:"fleet.bootstrap",input:{serverId:E,steps:d},lockKey:`server:${E}`,providerKey:_.provider}).operation;return{preview:!1,steps:d,operation:R}}heartbeat(E,T){let _=this.store.get(E);if(!_)throw Error("Server was not found.");let d=this.now().toISOString();return this.store.update(E,{usage:T.usage,capabilities:T.capabilities??_.capabilities,heartbeatAt:d,lastSeenAt:d,status:_.status==="draining"||_.status==="drained"?_.status:"ready"})}drain(E,T=!1){return this.store.update(E,{status:T?"drained":"draining"})}uncordon(E){return this.store.update(E,{status:"ready"})}archive(E,T){let _=this.store.get(E);if(!_||T!==_.name)throw Error("Exact server name confirmation is required.");return this.store.update(E,{status:"archived",archivedAt:this.now().toISOString()})}}async function jb(){let E=await o(),T=lE(process.cwd(),E),_=new nR(T.store),d=new gt(_,[new eh("aws"),new eh("hetzner"),new eh("ssh")]);return{controlPlane:T,store:_,service:d}}async function Gh(E){let T=await jb();try{return await E(T)}finally{T.controlPlane.store.close()}}var ZN=(E,T)=>{let _=E.store.list(E.controlPlane.project.id).find((d)=>d.id===T||d.name===T);if(!_)throw Error(`Server ${T} was not found.`);return _},sd=(E)=>{Q(E instanceof Error?E.message:String(E)),process.exitCode=1};function PX(E,T){let _=Number.parseInt(E??"",10);return Number.isFinite(_)&&_>=0?_:T}function Bb(E="3h"){let T=E.match(/^(\d+)(m|h)$/);if(!T)throw Error("--range must use minutes or hours, for example 30m or 3h.");let _=Number(T[1])*(T[2]==="h"?3600000:60000);if(_<300000||_>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return _}function bt(E,T="%"){return E==null?"unavailable":`${E.toFixed(1)}${T}`}async function Wb(E,T){let _=await o();if(_.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let d=T.env??process.env.CLOUD_ENV??"production",R=IT(_,d),h=await IR(R);if(!h?.serverId)throw Error(`No pinned Hetzner server was found for ${R}.`);if(![h.serverName,String(h.serverId),h.stackName].includes(E))throw Error(`Refusing to read ${E}: project state is pinned to ${h.serverName}.`);let r=$S(_),N=new Wh({apiToken:Qr(r.apiToken,_)}),A=await N.getServer(h.serverId),S=h.publicIp??A.public_net.ipv4?.ip;if(!S)throw Error(`Server ${A.name} has no public IPv4 address.`);let L=new Date,t=new Date(L.getTime()-Bb(T.range)),O=Math.min(3600,Math.max(60,PX(T.step,60))),U=await ey({client:N,serverId:A.id,cores:Math.max(1,Number(A.server_type.cores)||1),from:t,to:L,step:O,remote:{host:S,user:h.sshUser??r.sshUser,identityFile:r.sshPrivateKeyPath,connectTimeoutSec:15}});if(T.json){console.log(JSON.stringify({schemaVersion:1,server:A.name,result:U},null,2));return}EE(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[A.name,`${U.from} to ${U.to}`,`${bt(U.summary.cpuAveragePercent)} / ${bt(U.summary.cpuPeakPercent)}`,`${bt(U.summary.memoryAveragePercent)} / ${bt(U.summary.memoryPeakPercent)}`,U.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(U.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,bt(U.summary.swapPeakPercent)]])}function iy(E){let T=E.targetType.prices?.find((_)=>_.location===E.location);return{serverId:E.serverId,serverName:E.serverName,location:E.location,from:E.currentType.name,to:E.targetType.name,capacityAvailable:E.capacityAvailable,alreadyComplete:E.alreadyComplete,upgradeDisk:E.upgradeDisk,target:{cores:E.targetType.cores,memoryGb:E.targetType.memory,diskGb:E.targetType.disk,architecture:E.targetType.architecture,cpuType:E.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 Hb(E){let T=iy(E);EE(["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 yb(E,T,_){let d=await o();if(d.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let R=_.env??process.env.CLOUD_ENV??"production",h=IT(d,R),r=await IR(h),N=$S(d),A=new Wh({apiToken:Qr(N.apiToken,d)}),L=r&&(E===r.serverName||E===String(r.serverId)||E===r.stackName)?await A.getServer(r.serverId):(await A.listServers()).find((e)=>e.name===E||String(e.id)===E);if(!L)throw Error(`Hetzner server ${E} was not found.`);if(r?.serverId&&r.serverId!==L.id)throw Error(`Refusing to resize ${E}: project state is pinned to server ${r.serverId}.`);let t=Hh(T),O=_.upgradeDisk!==!1,U=await xt(A,L.id,t,O);if(_.json)console.log(JSON.stringify({schemaVersion:1,plan:iy(U)},null,2));else Hb(U);if(!_.apply){if(!_.json)$(`Preview only. Re-run with --apply --confirm ${L.name} to execute.`);return}if(_.confirm!==L.name)throw Error(`Resize requires --confirm ${L.name}.`);let D=r?.publicIp??L.public_net.ipv4?.ip;if(!D)throw Error(`Server ${L.name} has no public IPv4 address for verification.`);let C={host:D,user:r?.sshUser??N.sshUser,identityFile:N.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},w=await MX(h),c=new Date().toISOString(),z={schemaVersion:1,operationId:w?.targetType===t&&w.serverId===L.id?w.operationId:crypto.randomUUID(),stackName:h,serverId:L.id,serverName:L.name,sourceType:U.currentType.name,targetType:t,upgradeDisk:O,phase:"planning",status:"running",attempts:w?.targetType===t?w.attempts:0,startedAt:w?.targetType===t?w.startedAt:c,updatedAt:c,manifest:w?.targetType===t?w.manifest:void 0};await Yh(z);let j=PX(_.pollSeconds,900)*1000,W=PX(_.maxWaitMinutes,0)*60000,G=Date.now();for(;;){let e=await xt(A,L.id,t,O);if(!e.capacityAvailable&&!e.alreadyComplete){if(z={...z,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await Yh(z),!_.wait){if(!_.json)$(`${t} has no capacity in ${e.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(W>0&&Date.now()-G>=W)throw Error(`Timed out waiting for ${t} capacity in ${e.location}.`);if(!_.json)$(`Waiting ${Math.round(j/1000)} seconds for ${t} capacity...`);await Bun.sleep(j);continue}let V=await VX(h);try{let P=await(async()=>{try{return z={...z,status:"running",attempts:z.attempts+1,updatedAt:new Date().toISOString()},await Yh(z),await HX({client:A,serverId:L.id,targetType:t,upgradeDisk:O,resumeFromOff:z.phase==="shutting-down"||z.phase==="resizing"||z.phase==="powering-on"||z.phase==="verifying",manifest:z.manifest,hooks:{preflight:async()=>{let g=await YX(C);return z={...z,manifest:g,updatedAt:new Date().toISOString()},await Yh(z),g},afterBoot:async(g,k,v,TE)=>eX(C,k,v,TE),onPhase:async(g,k)=>{if(z={...z,phase:g,status:g==="waiting-capacity"?"waiting-capacity":g==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await Yh(z),!_.json)$(`${g}${k?` ${JSON.stringify(k)}`:""}`)}}})}finally{await V()}})();if(z={...z,status:P.status==="completed"||P.status==="already-complete"?"completed":P.status==="recovered"?"recovered":"waiting-capacity",lastError:P.status==="recovered"?P.error:void 0,updatedAt:new Date().toISOString()},await Yh(z),_.json)console.log(JSON.stringify({schemaVersion:1,result:P},null,2));else if(P.status==="completed"||P.status==="already-complete")Z(`${L.name} is on ${t} and passed full post-boot verification.`);else if(P.status==="recovered"&&P.retryable&&_.wait){$(`Capacity race recovered safely. Waiting ${Math.round(j/1000)} seconds before retry.`),await Bun.sleep(j);continue}else if(P.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${P.error}`);return}catch(P){throw z={...z,status:"failed",lastError:P instanceof Error?P.message:String(P),updatedAt:new Date().toISOString()},await Yh(z),P}}}async function Yb(E,T){let _=await o();if(_.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let d=T.env??process.env.CLOUD_ENV??"production",R=IT(_,d),h=await IR(R);if(!h?.serverId)throw Error(`No pinned Hetzner server was found for ${R}.`);if(![h.serverName,String(h.serverId),h.stackName].includes(E))throw Error(`Refusing to optimize ${E}: project state is pinned to ${h.serverName}.`);let r=$S(_),N=new Wh({apiToken:Qr(r.apiToken,_)}),A=await N.getServer(h.serverId),S=h.publicIp??A.public_net.ipv4?.ip;if(!S)throw Error(`Server ${A.name} has no public IPv4 address.`);let L=M$(_);if(T.json)console.log(JSON.stringify({schemaVersion:1,server:A.name,plan:L},null,2));else EE(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[A.name,L.firewallPorts.join(","),L.monitoring?"on":"off",L.autoUpdates?"on":"off",`${L.swapGb} GB`,"disabled"]]);if(!T.apply){if(!T.json)$(`Preview only. Re-run with --apply --confirm ${A.name} to execute.`);return}if(T.confirm!==A.name)throw Error(`Optimization requires --confirm ${A.name}.`);let t={host:S,user:h.sshUser??r.sshUser,identityFile:r.sshPrivateKeyPath,connectTimeoutSec:15},O=await FS(t),U=O.routeProbes.filter((v)=>!v.ok),D=_.infrastructure?.compute,C=Nd(D)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,w=O.failedUnits.filter((v)=>!C.has(v));if(w.length>0)throw Error(`Preflight found failed services: ${w.join(", ")}`);if(U.length>0)throw Error(`Preflight found unhealthy routes: ${U.map((v)=>v.domain).join(", ")}`);let c=Nd(D)?[]:Object.values(_.sites??{}).flatMap((v)=>typeof v?.port==="number"&&![80,443].includes(v.port)?[v.port]:[]),z=CS({allowSsh:D?.allowSsh!==!1,sitePorts:c,allowedPorts:D?.firewall?.allowedPorts}),j=(h.firewallId?(await N.listFirewalls()).find((v)=>v.id===h.firewallId):void 0)??(await N.listFirewalls()).find((v)=>v.name===`${_.project.slug}-${d}-app-fw`);if(!j)throw Error(`Managed firewall for ${A.name} was not found.`);let W=await N.setFirewallRules(j.id,z);await Promise.all(W.map((v)=>N.waitForAction(v.id))),await XX(_,t);let[G,e]=await Promise.all([FS(t),JX(t)]),V=FX(L,e),P=fy(O,G),g=G.routeProbes.filter((v)=>!v.ok);if(P.stoppedServices.length>0)V.push(`services stopped: ${P.stoppedServices.join(", ")}`);if(P.changedRouteFragments.length>0)V.push(`route fragments changed: ${P.changedRouteFragments.join(", ")}`);if(P.missingRouteIds.length>0)V.push(`routes disappeared: ${P.missingRouteIds.join(", ")}`);if(P.changedReleaseLinks.length>0)V.push(`release links changed: ${P.changedReleaseLinks.join(", ")}`);if(P.missingData.length>0)V.push(`databases or volumes disappeared: ${P.missingData.join(", ")}`);if(g.length>0)V.push(`unhealthy routes: ${g.map((v)=>v.domain).join(", ")}`);if(V.length>0)throw Error(`Host optimization verification failed: ${V.join("; ")}`);let k={serverId:A.id,serverName:A.name,services:G.runningServices.length,routes:G.routeIds.length,healthyDomains:G.routeProbes.length,releaseLinks:G.releaseLinks.length,databasesAndVolumes:G.dataCatalog.length,report:e};if(T.json)console.log(JSON.stringify({schemaVersion:1,result:k},null,2));else Z(`${A.name} passed full host, rpx route, service, release, and data verification.`)}function ZX(E){E.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(T,_)=>{try{await Gh(async(d)=>{let R=T?[ZN(d,T)]:d.store.list(d.controlPlane.project.id),h=R.flatMap((r)=>Object.entries(r.capabilities).map(([N,A])=>({server:r.name,provider:r.provider,action:N,...A})));if(_.json)console.log(JSON.stringify({schemaVersion:1,targets:h},null,2));else EE(["Server","Provider","Action","Support","Explanation"],h.map((r)=>[r.server,r.provider,r.action,r.supported?"supported":"unsupported",r.reason??"—"]))})}catch(d){sd(d)}}),E.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,_,d)=>{try{await yb(T,_,d)}catch(R){sd(R)}}),E.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,_)=>{try{await Yb(T,_)}catch(d){sd(d)}}),E.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,_)=>{try{await Wb(T,_)}catch(d){sd(d)}}),E.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(T)=>{try{await Gh(async(_)=>{let d=_.store.list(_.controlPlane.project.id);if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],d.map((R)=>[R.name,R.providerId??"—",`${R.provider} / ${R.region??"external"}`,`${R.status} / ${R.trustState}`,R.roles.join(","),`${R.capacity.cpu??0} / ${R.capacity.memoryBytes??0}`,R.heartbeatAt??"never"]))})}catch(_){sd(_)}}),E.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,_)=>{try{await Gh(async(d)=>{let R=_.provider;if(!["aws","hetzner","ssh"].includes(R)||!_.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let h=d.service.enroll({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,provider:R,providerId:_.providerId,endpoint:_.endpoint,sshUser:_.user??"deploy",credentialRef:_.credentialRef??"secret://fleet/agent",region:_.region,roles:String(_.roles??"application").split(","),labels:Object.fromEntries(String(_.labels??"").split(",").map((r)=>r.split("=")).filter((r)=>r[0]&&r[1]))});Z(`Enrolled ${h.name} as ${h.id}; no remote mutation was performed.`)})}catch(d){sd(d)}}),E.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,_)=>{try{await Gh(async(d)=>{let R=ZN(d,T);if(R=await d.service.test(R.id),R.trustState==="rotation_pending"){if(!_.acceptHostKey)throw Error(`Host key changed to ${R.pendingHostKey}; review it first.`);R=d.service.reviewHostKey(R.id,_.acceptHostKey)}let h=await d.service.validate(R.id);if(_.json)console.log(JSON.stringify(h.validation,null,2));else EE(["Severity","Code","Finding","Remediation"],(h.validation?.findings??[]).map((r)=>[r.severity,r.code,r.message,r.remediation??"—"]));if(!h.validation?.valid)process.exitCode=1})}catch(d){sd(d)}}),E.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(T,_)=>{try{await Gh(async(d)=>{let R=d.service.bootstrap(ZN(d,T).id,!!_.apply);if(R.preview)EE(["Step"],R.steps.map((h)=>[h]));else Z(`Bootstrap queued: ${R.operation?.id}`)})}catch(d){sd(d)}}),E.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(T,_)=>{try{await Gh(async(d)=>Z(d.service.drain(ZN(d,T).id,!!_.complete).status))}catch(d){sd(d)}}),E.command("server:uncordon <name>","Return a server to scheduling").action(async(T)=>{try{await Gh(async(_)=>{_.service.uncordon(ZN(_,T).id),Z(`Uncordoned ${T}.`)})}catch(_){sd(_)}}),E.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(T,_)=>{try{await Gh(async(d)=>{d.service.archive(ZN(d,T).id,_.confirm??""),Z(`Archived ${T}; provider infrastructure was not terminated.`)})}catch(d){sd(d)}}),E.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(T)=>{try{await Gh(async(_)=>{let d=ZN(_,T);if(d.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let R=Bun.spawn(["ssh","-p",String(d.sshPort),"-o","StrictHostKeyChecking=yes",`${d.sshUser}@${d.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),h=await R.exited;if(h)process.exitCode=h})}catch(_){sd(_)}});for(let[T,_]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])E.command(T,_).action(async(...d)=>ld(T.split(" ")[0],{target:String(d[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}ME();var CR=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},Ad=(E)=>E==null?void 0:String(E),sy=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),jS=(E={})=>({...sy(),...E});function my(E){return{id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),name:String(E.name),purpose:String(E.purpose),backend:String(E.backend),region:Ad(E.region),architecture:Ad(E.architecture),labels:CR(E.labels,{}),requiredServerLabels:CR(E.required_server_labels,{}),toleratedTaints:CR(E.tolerated_taints,[]),capacity:jS(CR(E.capacity,{})),reserved:CR(E.reserved,{}),maxWorkloads:Number(E.max_workloads),costWeight:Number(E.cost_weight),spreadKey:Ad(E.spread_key),concurrency:Number(E.concurrency),ephemeralWorkspaces:Number(E.ephemeral_workspaces)===1,allowProductionSecrets:Number(E.allow_production_secrets)===1,status:String(E.status),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}function ay(E){return{id:String(E.id),projectId:String(E.project_id),environmentId:Ad(E.environment_id),resourceId:String(E.resource_id),releaseId:Ad(E.release_id),poolId:String(E.pool_id),serverId:Ad(E.server_id),purpose:String(E.purpose),requirements:CR(E.requirements,{}),decision:CR(E.decision,{}),stateful:Number(E.stateful)===1,autoReschedule:Number(E.auto_reschedule)===1,status:String(E.status),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}function eb(E){return{id:String(E.id),projectId:String(E.project_id),resourceId:Ad(E.resource_id),poolId:String(E.pool_id),placementId:Ad(E.placement_id),operationId:Ad(E.operation_id),sourceSha:String(E.source_sha),buildSpec:CR(E.build_spec,{}),credentialPolicy:CR(E.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:Ad(E.workspace),cacheKey:Ad(E.cache_key),artifactUri:Ad(E.artifact_uri),artifactDigest:Ad(E.artifact_digest),status:String(E.status),cleanupAt:Ad(E.cleanup_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}}class kt{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}createPool(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[T,E.organizationId,E.projectId,E.name,E.purpose,E.backend,E.region??null,E.architecture??null,JSON.stringify(E.labels),JSON.stringify(E.requiredServerLabels),JSON.stringify(E.toleratedTaints),JSON.stringify(jS(E.capacity)),"{}",E.maxWorkloads,E.costWeight,E.spreadKey??null,E.concurrency,E.ephemeralWorkspaces?1:0,E.allowProductionSecrets?1:0,E.status,_,_]),this.getPool(T)}getPool(E){let T=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(E);return T?my(T):void 0}listPools(E){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(E).map(my)}updatePool(E,T){let _=this.getPool(E);if(!_)throw Error("Capacity pool was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.reserved),JSON.stringify(d.capacity),d.concurrency,R,E]),this.getPool(E)}addMember(E,T,_={}){let d=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[E,T,JSON.stringify(_),d,d])}members(E){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(E).map((T)=>({serverId:String(T.server_id),status:String(T.status),capacityOverride:CR(T.capacity_override,{})}))}memberStatus(E,T,_){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[_,this.now().toISOString(),E,T])}listPlacements(E,T){let _=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(E).map(ay);return T?.length?_.filter((d)=>T.includes(d.status)):_}getPlacement(E){let T=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(E);return T?ay(T):void 0}activeUsage(E,T){let _=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(E,this.now().toISOString()),d=T?_.filter((R)=>String(R.server_id)===T):_;return{resources:d.reduce((R,h)=>{let r=jS(CR(h.resources,{}));for(let N of Object.keys(R))R[N]+=r[N];return R},sy()),count:d.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(E){return this.control.transaction(()=>{this.expireLeases();let T=this.id(),_=this.id(),d=this.now().toISOString(),R=new Date(this.now().getTime()+(E.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[T,E.projectId,E.environmentId??null,E.resourceId,E.releaseId??null,E.decision.poolId,E.decision.serverId??null,E.requirements.purpose,JSON.stringify(E.requirements),JSON.stringify(E.decision),E.requirements.stateful?1:0,E.requirements.autoReschedule&&!E.requirements.stateful?1:0,d,d]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[_,T,E.decision.poolId,E.decision.serverId??null,JSON.stringify(jS(E.requirements.resources)),R,d,d]),this.getPlacement(T)})}transitionPlacement(E,T){if(!this.getPlacement(E))throw Error("Placement was not found.");let d=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[T,d,E]),["released","failed","blocked"].includes(T))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[d,E]);return this.getPlacement(E)}createBuild(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[T,E.projectId,E.resourceId??null,E.poolId,E.placementId??null,E.operationId??null,E.sourceSha,JSON.stringify(E.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:E.tokenExpiresAt}),_,_]),this.getBuild(T)}getBuild(E){let T=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(E);return T?eb(T):void 0}updateBuild(E,T){let _=this.getBuild(E);if(!_)throw Error("Remote build was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[d.operationId??null,d.workspace??null,d.cacheKey??null,d.artifactUri??null,d.artifactDigest??null,d.status,d.cleanupAt??null,R,E]),this.getBuild(E)}}var P$=["cpu","memoryBytes","diskBytes","gpu"],py=(E,T={})=>Object.entries(T).every(([_,d])=>E[_]===d),Gb=(E,T,_)=>Object.fromEntries(P$.map((d)=>[d,Math.max(0,E[d]-T[d]-(_[d]??0))])),Qb=(E,T)=>P$.every((_)=>E[_]>=(T[_]??0)),Mb=(E,T)=>P$.reduce((_,d)=>_+(T[d]??0)/(E[d]||1),0);class ut{store;fleet;constructor(E,T){this.store=E;this.fleet=T}poolCandidates(E,T,_){let d=[];for(let R of this.store.listPools(E)){if(R.id===_)continue;let h=[];if(R.status!=="active")h.push(`pool is ${R.status}`);if(R.purpose!==T.purpose)h.push(`purpose is ${R.purpose}`);if(T.region&&R.region!==T.region)h.push(`region is ${R.region??"unset"}`);if(T.architecture&&R.architecture!==T.architecture)h.push(`architecture is ${R.architecture??"unset"}`);if(!py(R.labels,T.labels))h.push("pool labels do not match");if(R.backend==="server"){let r=this.store.members(R.id);if(!r.length)d.push(this.decision(R,void 0,T,[...h,"pool has no servers"]));for(let N of r){let A=this.fleet.get(N.serverId),S=[...h];if(!A)S.push("server is missing");else this.serverReasons(R,A,N.status,T,S);d.push(this.decision(R,A,T,S,N.capacityOverride))}}else d.push(this.decision(R,void 0,T,h))}return d.sort((R,h)=>Number(h.eligible)-Number(R.eligible)||R.score.cost-h.score.cost||R.score.spread-h.score.spread||R.score.fit-h.score.fit||R.poolName.localeCompare(h.poolName)||(R.serverId??"").localeCompare(h.serverId??""))}serverReasons(E,T,_,d,R){if(_!=="active")R.push(`member is ${_}`);if(T.status!=="ready")R.push(`server is ${T.status}`);if(!T.roles.includes(d.purpose==="build"?"build":d.purpose))R.push(`server lacks ${d.purpose} role`);if(!py(T.labels,E.requiredServerLabels))R.push("server labels do not match pool selector");for(let h of T.taints)if(!E.toleratedTaints.includes(h))R.push(`taint ${h} is not tolerated`)}decision(E,T,_,d,R={}){let h=jS({...T?.capacity,...R}),r=T?Object.fromEntries(P$.map((S)=>[S,Math.min(E.capacity[S],h[S])])):E.capacity,N=this.store.activeUsage(E.id,T?.id),A=Gb(r,N.resources,E.reserved);if(N.count>=E.maxWorkloads)d.push("workload limit reached");if(_.purpose==="build"&&N.count>=E.concurrency)d.push("build concurrency reached");if(!Qb(A,_.resources))d.push("insufficient capacity");return{poolId:E.id,poolName:E.name,serverId:T?.id,eligible:d.length===0,reasons:d,available:A,score:{fit:Mb(A,_.resources),spread:N.count,cost:E.costWeight}}}explain(E,T){return this.poolCandidates(E,T)}place(E){return this.store.control.transaction(()=>{let T=this.poolCandidates(E.projectId,E.requirements).find((_)=>_.eligible);if(!T)throw Error(`No eligible capacity: ${this.explain(E.projectId,E.requirements).flatMap((_)=>_.reasons).join("; ")}`);return this.store.reserve({...E,decision:T})})}activate(E){return this.store.transitionPlacement(E,"active")}release(E){return this.store.transitionPlacement(E,"released")}drainPool(E){let T=this.store.updatePool(E,{status:"draining"}),_=[],d=[];for(let R of this.store.listPlacements(T.projectId,["reserved","active"]).filter((h)=>h.poolId===E)){if(R.stateful){d.push(this.store.transitionPlacement(R.id,"blocked"));continue}this.store.transitionPlacement(R.id,"moving");let h=this.place({projectId:R.projectId,environmentId:R.environmentId,resourceId:R.resourceId,releaseId:R.releaseId,requirements:R.requirements});_.push(this.activate(h.id)),this.store.transitionPlacement(R.id,"released")}return{pool:T,moved:_,blocked:d}}drainServer(E,T){this.store.memberStatus(E,T,"draining");let _=this.store.getPool(E);if(!_)throw Error("Capacity pool was not found.");let d=[],R=[];for(let h of this.store.listPlacements(_.projectId,["reserved","active"]).filter((r)=>r.poolId===E&&r.serverId===T)){if(h.stateful){R.push(this.store.transitionPlacement(h.id,"blocked"));continue}this.store.transitionPlacement(h.id,"moving");let r=this.poolCandidates(h.projectId,h.requirements).find((A)=>A.eligible);if(!r){R.push(this.store.transitionPlacement(h.id,"blocked"));continue}let N=this.store.reserve({projectId:h.projectId,environmentId:h.environmentId,resourceId:h.resourceId,releaseId:h.releaseId,requirements:h.requirements,decision:r});d.push(this.activate(N.id)),this.store.transitionPlacement(h.id,"released")}return{moved:d,blocked:R}}reconcileFailure(E){let T=this.fleet.get(E);if(!T)throw Error("Server was not found.");let _=[],d=[];for(let R of this.store.listPlacements(T.projectId,["active"]).filter((h)=>h.serverId===E)){if(R.stateful||!R.autoReschedule){d.push(this.store.transitionPlacement(R.id,"blocked"));continue}this.store.transitionPlacement(R.id,"failed");let h=this.place({projectId:R.projectId,environmentId:R.environmentId,resourceId:R.resourceId,releaseId:R.releaseId,requirements:R.requirements});_.push(this.activate(h.id))}return{rescheduled:_,blocked:d}}}async function Vb(){let E=await o(),T=lE(process.cwd(),E),_=new kt(T.store),d=new ut(_,new nR(T.store));return{controlPlane:T,store:_,service:d}}async function vt(E){let T=await Vb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}var Z$=(E)=>Object.fromEntries(String(E??"").split(",").map((T)=>T.split("=")).filter((T)=>T[0]&&T[1])),oy=(E)=>Object.fromEntries(Object.entries(Z$(E)).map(([T,_])=>[T,Number(_)]));function qX(E){E.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(T)=>vt((_)=>{let d=_.store.listPools(_.controlPlane.project.id);if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],d.map((R)=>[R.name,R.purpose,R.backend,`${R.region??"any"} / ${R.architecture??"any"}`,R.status,JSON.stringify(R.capacity),String(R.concurrency)]))})),E.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,_)=>vt((d)=>{let{purpose:R,backend:h}=_;if(!["application","build","worker","monitoring","backup"].includes(R)||!["server","ecs","asg"].includes(h))throw Error("Unsupported pool purpose or backend.");let r=d.store.createPool({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,purpose:R,backend:h,region:_.region,architecture:_.arch,labels:Z$(_.labels),requiredServerLabels:Z$(_.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...oy(_.capacity)},maxWorkloads:Number(_.max),costWeight:1,concurrency:Number(_.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});Z(`Created ${r.name} (${r.id}).`)})),E.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(T,_)=>vt((d)=>{let R=d.store.listPools(d.controlPlane.project.id).find((r)=>r.id===T||r.name===T),h=new nR(d.controlPlane.store).list(d.controlPlane.project.id).find((r)=>r.id===_||r.name===_);if(!R||!h)throw Error("Pool or server was not found.");d.store.addMember(R.id,h.id),Z(`Attached ${h.name} to ${R.name}.`)})),E.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)=>vt((_)=>{let d=_.service.explain(_.controlPlane.project.id,{purpose:T.purpose,resources:oy(T.resources),region:T.region,architecture:T.arch,labels:Z$(T.labels)});if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],d.map((R)=>[R.poolName,R.serverId??"provider-managed",R.eligible?"yes":"no",JSON.stringify(R.available),`${R.score.fit.toFixed(2)} / ${R.score.spread} / ${R.score.cost}`,R.reasons.join("; ")||"eligible"]))})),E.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(T)=>vt((_)=>{let d=_.store.listPools(_.controlPlane.project.id).find((h)=>h.id===T||h.name===T);if(!d)throw Error("Pool was not found.");let R=_.service.drainPool(d.id);Z(`Draining ${d.name}: moved ${R.moved.length}, blocked ${R.blocked.length} stateful placement(s).`)}))}ME();var Qh=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},pd=(E)=>E==null?void 0:String(E),E5=(E)=>({id:String(E.id),organizationId:String(E.organization_id),projectId:String(E.project_id),environmentId:pd(E.environment_id),name:String(E.name),hostname:String(E.hostname),homeRegion:String(E.home_region),regions:Qh(E.regions,[]),trafficPolicy:String(E.traffic_policy),dataPolicy:Qh(E.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(E.status),activeRegion:String(E.active_region),revision:pd(E.revision),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),xX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),region:String(E.region),role:String(E.role),provider:String(E.provider),stackId:pd(E.stack_id),stackRevision:pd(E.stack_revision),status:String(E.status),health:Qh(E.health,{}),lastHealthyAt:pd(E.last_healthy_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),gX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),kind:String(E.kind),sourceRegion:String(E.source_region),targetRegion:String(E.target_region),config:Qh(E.config,{}),status:String(E.status),checkpoint:pd(E.checkpoint),lagSeconds:E.lag_seconds==null?void 0:Number(E.lag_seconds),lastVerifiedAt:pd(E.last_verified_at),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),bX=(E)=>({id:String(E.id),topologyId:String(E.topology_id),hostname:String(E.hostname),dnsProvider:String(E.dns_provider),cdnEnabled:Number(E.cdn_enabled)===1,wafEnabled:Number(E.waf_enabled)===1,weights:Qh(E.weights,{}),desiredWeights:Qh(E.desired_weights,{}),status:String(E.status),providerState:Qh(E.provider_state,{}),version:Number(E.version),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),T5=(E)=>({id:String(E.id),topologyId:String(E.topology_id),operationId:pd(E.operation_id),kind:String(E.kind),requestedRegion:pd(E.requested_region),revision:pd(E.revision),plan:Qh(E.plan,[]),currentStep:pd(E.current_step),completedSteps:Qh(E.completed_steps,[]),status:String(E.status),error:pd(E.error),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class nt{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}create(E){return this.control.transaction(()=>{if(E.regions.length<2||new Set(E.regions.map((h)=>h.region)).size!==E.regions.length||E.regions.filter((h)=>h.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let T=E.regions.find((h)=>h.role==="primary"),_=this.id(),d=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[_,E.organizationId,E.projectId,E.environmentId??null,E.name,E.hostname,T.region,JSON.stringify(E.regions),E.trafficPolicy,JSON.stringify(E.dataPolicy),T.region,d,d]);for(let h of E.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),_,h.region,h.role,h.provider,d,d]);for(let h of E.dataPolicy.replicate)for(let r of E.regions)for(let N of E.regions.filter((A)=>A.region!==r.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),_,h,r.region,N.region,"{}",d,d]);let R=Object.fromEntries(E.regions.map((h)=>[h.region,h.region===T.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),_,E.hostname,E.dnsProvider??"route53",E.cdnEnabled?1:0,E.wafEnabled?1:0,JSON.stringify(R),JSON.stringify(R),d,d]),this.get(_)})}get(E){let T=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(E);return T?E5(T):void 0}list(E){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(E).map(E5)}targets(E){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(E).map(xX)}channels(E){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(E).map(gX)}route(E){let T=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(E);return T?bX(T):void 0}updateTopology(E,T){let _=this.get(E);if(!_)throw Error("Regional topology was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[d.status,d.activeRegion,d.revision??null,JSON.stringify(d.regions),R,E]),this.get(E)}updateTarget(E,T){let _=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(E);if(!_)throw Error("Regional target was not found.");let d=xX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[R.role,R.stackId??null,R.stackRevision??null,R.status,JSON.stringify(R.health),R.lastHealthyAt??null,h,E]),xX(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(E))}updateChannel(E,T){let _=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(E);if(!_)throw Error("Replication channel was not found.");let d=gX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[R.status,R.checkpoint??null,R.lagSeconds??null,R.lastVerifiedAt??null,h,E]),gX(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(E))}updateRoute(E,T){let _=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(E);if(!_)throw Error("Traffic route was not found.");let d=bX(_),R={...d,...T},h=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(R.weights),JSON.stringify(R.desiredWeights),R.status,JSON.stringify(R.providerState),h,E]),bX(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(E))}createExecution(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[T,E.topologyId,E.operationId??null,E.kind,E.requestedRegion??null,E.revision??null,JSON.stringify(E.plan),_,_]),this.execution(T)}execution(E){let T=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(E);return T?T5(T):void 0}executions(E){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(E).map(T5)}updateExecution(E,T){let _=this.execution(E);if(!_)throw Error("Regional execution was not found.");let d={..._,...T},R=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[d.operationId??null,d.currentStep??null,JSON.stringify(d.completedSteps),d.status,d.error??null,R,E]),this.execution(E)}}class lt{store;queue;constructor(E,T){this.store=E;this.queue=T??new nE(E.control)}create(E){return this.store.create(E)}plan(E,T,_){if(!this.store.get(E))throw Error("Regional topology was not found.");let R=this.store.targets(E),h=this.store.channels(E);if(T==="rollout")return[...R.filter((r)=>r.role==="secondary").map((r)=>`apply:${r.region}`),...R.filter((r)=>r.role==="primary").map((r)=>`apply:${r.region}`),...h.map((r)=>`replicate:${r.kind}:${r.targetRegion}`),"traffic:activate"];if(T==="failover"||T==="failback")return[`health:${_}`,`replication:${_}`,`traffic:${_}`,`roles:${_}`];if(T==="destroy")return["traffic:drain",...R.filter((r)=>r.role==="secondary").map((r)=>`delete:${r.region}`),...R.filter((r)=>r.role==="primary").map((r)=>`delete:${r.region}`),"complete"];return["observe","repair"]}enqueue(E){let T=this.store.get(E.topologyId);if(!T)throw Error("Regional topology was not found.");if(["failover","failback"].includes(E.kind)&&(!E.targetRegion||!T.regions.some((h)=>h.region===E.targetRegion)))throw Error("A topology target region is required.");if(E.kind==="failover"&&E.targetRegion===T.activeRegion)throw Error("Target region is already active.");if((E.kind==="destroy"||E.deleteData)&&E.confirmation!==T.name)throw Error("Exact topology name confirmation is required.");if(E.deleteData&&T.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(E.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(E.revision??""))throw Error("An immutable revision is required.");let _=this.plan(T.id,E.kind,E.targetRegion),d=this.store.createExecution({topologyId:T.id,kind:E.kind,requestedRegion:E.targetRegion,revision:E.revision,plan:_}),R=this.queue.enqueue({projectId:T.projectId,environmentId:T.environmentId,kind:`region.${E.kind}`,input:{executionId:d.id,manifest:E.manifest??{},deleteData:E.deleteData===!0},lockKey:`regional-topology:${T.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(d.id,{operationId:R.id}),{execution:this.store.execution(d.id),operation:R}}}var Kb=(E)=>E&&typeof E==="object"&&!Array.isArray(E)?E:{};function _5(E,T){let _=(S)=>{let L=T.find((t)=>t.provider===S.provider);if(!L)throw Error(`No ${S.provider} regional driver is configured.`);return L},d=(S,L,t)=>{S.throwIfCancellationRequested(),S.checkpoint(t,t),E.updateExecution(L.id,{status:"running",currentStep:t,completedSteps:[...E.execution(L.id).completedSteps,t]})},R=async(S,L)=>{let t=E.route(S.id);if(!t)throw Error("Regional traffic route was not found.");let O=E.targets(S.id).find((D)=>D.region===S.activeRegion)??E.targets(S.id)[0];if(!O)throw Error("Regional traffic target was not found.");E.updateRoute(t.id,{status:"applying",desiredWeights:L});let U=await _(O).applyTraffic({route:E.route(S.id),topology:S,weights:L});E.updateRoute(t.id,{status:Object.values(L).every((D)=>D===0)?"drained":"in_sync",weights:L,providerState:U.providerState})},h=async(S,L,t,O)=>{E.updateTopology(t.id,{status:"provisioning"});let U=L.revision,D=O.manifest??{},C=E.targets(t.id).sort((c,z)=>Number(c.role==="primary")-Number(z.role==="primary"));for(let c of C){d(S,L,`apply:${c.region}`),E.updateTarget(c.id,{status:"provisioning"});let z=await _(c).applyStack({target:c,revision:U,manifest:D,signal:S.signal}),j=await _(c).health({target:E.updateTarget(c.id,{stackId:z.stackId,stackRevision:U})});if(!j.healthy)throw Error(`Regional health gate failed in ${c.region}.`);E.updateTarget(c.id,{status:"ready",health:j.evidence,lastHealthyAt:new Date().toISOString()})}for(let c of E.channels(t.id)){d(S,L,`replicate:${c.kind}:${c.targetRegion}`),E.updateChannel(c.id,{status:"configuring"});let z=C.find((G)=>G.region===c.sourceRegion),j=await _(z).configureReplication({channel:c,topology:t}),W=await _(z).verifyReplication({channel:E.updateChannel(c.id,{checkpoint:j.checkpoint,lagSeconds:j.lagSeconds}),topology:t});if(!W.healthy||W.lagSeconds>t.dataPolicy.maxLagSeconds)throw Error(`${c.kind} replication to ${c.targetRegion} exceeds the RPO.`);E.updateChannel(c.id,{status:"in_sync",checkpoint:W.checkpoint,lagSeconds:W.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(S,L,"traffic:activate");let w=Object.fromEntries(t.regions.map((c)=>[c.region,c.region===t.activeRegion?100:0]));return await R(t,w),E.updateTopology(t.id,{status:"ready",revision:U}),{revision:U,activeRegion:t.activeRegion}},r=async(S,L,t)=>{let O=L.requestedRegion,U=E.targets(t.id).find((w)=>w.region===O);if(!U)throw Error("Requested regional target was not found.");E.updateTopology(t.id,{status:L.kind==="failover"?"failing_over":"failing_back"}),d(S,L,`health:${O}`);let D=await _(U).health({target:U});if(!D.healthy)throw Error(`Target region ${O} is unhealthy.`);E.updateTarget(U.id,{status:"ready",health:D.evidence,lastHealthyAt:new Date().toISOString()}),d(S,L,`replication:${O}`);for(let w of E.channels(t.id).filter((c)=>c.targetRegion===O)){let c=await _(U).verifyReplication({channel:w,topology:t});if(!c.healthy||c.lagSeconds>t.dataPolicy.maxLagSeconds)throw Error(`${w.kind} replication is outside the failover RPO.`);E.updateChannel(w.id,{status:"in_sync",checkpoint:c.checkpoint,lagSeconds:c.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(S,L,`traffic:${O}`),await R(t,Object.fromEntries(t.regions.map((w)=>[w.region,w.region===O?100:0]))),d(S,L,`roles:${O}`);let C=t.regions.map((w)=>({...w,role:w.region===O?"primary":"secondary"}));for(let w of E.targets(t.id))E.updateTarget(w.id,{role:w.region===O?"primary":"secondary"});return E.updateTopology(t.id,{status:L.kind==="failover"?"failed_over":"ready",activeRegion:O,regions:C}),{activeRegion:O}},N=async(S,L,t,O)=>{E.updateTopology(t.id,{status:"destroying"}),d(S,L,"traffic:drain"),await R(t,Object.fromEntries(t.regions.map((D)=>[D.region,0])));let U=O.deleteData!==!0;for(let D of E.targets(t.id).sort((C,w)=>Number(C.role==="primary")-Number(w.role==="primary")))d(S,L,`delete:${D.region}`),E.updateTarget(D.id,{status:"deleting"}),await _(D).deleteStack({target:D,retainData:U,signal:S.signal}),E.updateTarget(D.id,{status:"deleted"});return d(S,L,"complete"),E.updateTopology(t.id,{status:"destroyed"}),{destroyed:!0,dataRetained:U}},A=async(S)=>{let L=Kb(S.operation.input),t=E.execution(String(L.executionId??""));if(!t)throw Error("Regional execution was not found.");let O=E.get(t.topologyId);if(!O)throw Error("Regional topology was not found.");try{let U;if(t.kind==="rollout")U=await h(S,t,O,L);else if(t.kind==="failover"||t.kind==="failback")U=await r(S,t,O);else if(t.kind==="destroy")U=await N(S,t,O,L);else throw Error("Regional reconciliation is not configured.");return E.updateExecution(t.id,{status:"succeeded",currentStep:void 0}),{executionId:t.id,...U}}catch(U){if(E.updateExecution(t.id,{status:S.cancellationRequested()?"cancelled":"failed",error:U instanceof Error?U.message:String(U)}),E.get(O.id)?.status!=="destroyed")E.updateTopology(O.id,{status:"failed"});throw U}};return{"region.rollout":A,"region.failover":A,"region.failback":A,"region.destroy":A,"region.reconcile":A}}class kX{provider;reason;constructor(E,T="Configure a regional provider transport before executing this operation."){this.provider=E;this.reason=T}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}async function fb(){let E=await o(),T=lE(process.cwd(),E),_=new nt(T.store),d=new lt(_);return{controlPlane:T,store:_,service:d}}async function qN(E){let T=await fb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}var it=(E,T)=>{let _=E.store.list(E.controlPlane.project.id).find((d)=>d.id===T||d.name===T);if(!_)throw Error("Regional topology was not found.");return _},Pb=(E)=>E.split(",").map((T,_)=>{let[d,R="aws"]=T.split(":");return{region:String(d),provider:R,role:_===0?"primary":"secondary"}}),Zb=(E)=>{let T=new Set(["s3","dynamodb","secrets"]),_=E.split(",").map((R)=>R.trim()),d=_.find((R)=>!T.has(R));if(d)throw Error(`Unsupported replication kind: ${d}`);return _};function uX(E){E.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(T)=>qN((_)=>{let d=_.store.list(_.controlPlane.project.id).map((R)=>({topology:R,targets:_.store.targets(R.id),channels:_.store.channels(R.id),route:_.store.route(R.id),executions:_.store.executions(R.id)}));if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Name","Hostname","Active","Status","Revision","Replication"],d.map((R)=>[R.topology.name,R.topology.hostname,R.topology.activeRegion,R.topology.status,R.topology.revision??"—",`${R.channels.filter((h)=>h.status==="in_sync").length}/${R.channels.length} in sync`]))})),E.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,_)=>qN((d)=>{if(!_.hostname||!_.regions)throw Error("--hostname and --regions are required.");let R=d.service.create({organizationId:d.controlPlane.organization.id,projectId:d.controlPlane.project.id,name:T,hostname:_.hostname,regions:Pb(_.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Zb(String(_.replicate)),maxLagSeconds:Number(_.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!_.cdn,wafEnabled:!!_.waf});Z(`Created ${R.name} (${R.id}); run region:rollout with an immutable manifest.`)})),E.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(T,_,d)=>qN((R)=>EE(["Step"],R.service.plan(it(R,T).id,_,d.target).map((h)=>[h])))),E.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(T,_,d)=>qN(async(R)=>{let h=d.manifest?await Bun.file(d.manifest).json():{},r=R.service.enqueue({topologyId:it(R,T).id,kind:"rollout",revision:_,manifest:h});Z(`Regional rollout queued: ${r.operation.id}`)})),E.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"failover",targetRegion:_});Z(`Failover queued: ${R.operation.id}`)})),E.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"failback",targetRegion:_});Z(`Failback queued: ${R.operation.id}`)})),E.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(T,_)=>qN((d)=>{let R=d.service.enqueue({topologyId:it(d,T).id,kind:"destroy",confirmation:_.confirm});Z(`Regional teardown queued: ${R.operation.id}; replicated data remains retained.`)}))}ME();var mt="0.7.75";import{createHash as vX,createPublicKey as h5,verify as xb}from"node:crypto";function at(E){if(E===null||typeof E!=="object")return JSON.stringify(E);if(Array.isArray(E))return`[${E.map(at).join(",")}]`;return`{${Object.keys(E).sort().map((T)=>`${JSON.stringify(T)}:${at(E[T])}`).join(",")}}`}var r5=(E)=>vX("sha256").update(at(E)).digest("hex"),q$=(E)=>vX("sha256").update(at(E)).digest("hex"),N5=(E)=>vX("sha256").update(h5(E).export({type:"spki",format:"der"})).digest("hex");function A5(E,T,_){try{return xb(null,Buffer.from(at(E)),h5(_),Buffer.from(T,"base64"))}catch{return!1}}var d5=(E)=>E.replace(/^v/,"").split(/[.-]/).slice(0,3).map((T)=>Number(T)||0),R5=(E,T)=>{let _=d5(E),d=d5(T);for(let R=0;R<3;R++){let h=(_[R]??0)-(d[R]??0);if(h)return h}return 0};function S5(E,T){let _=[];if(T.schemaVersion<E.minimumSchema)_.push(`schema ${T.schemaVersion} is below ${E.minimumSchema}`);if(T.schemaVersion>E.maximumSchema)_.push(`schema ${T.schemaVersion} is above ${E.maximumSchema}`);if(E.minimumVersion&&R5(T.currentVersion,E.minimumVersion)<0)_.push(`platform ${T.currentVersion} is below ${E.minimumVersion}`);if(R5(E.version,T.currentVersion)<=0)_.push(`version ${E.version} is not newer than ${T.currentVersion}`);if(!E.artifacts.some((d)=>d.platform===T.platform&&d.architecture===T.architecture))_.push(`no artifact for ${T.platform}/${T.architecture}`);return{compatible:_.length===0,reasons:_}}var Mh=(E,T)=>{try{return JSON.parse(String(E))}catch{return T}},F_=(E)=>E==null?void 0:String(E),gb=(E)=>({id:String(E.id),organizationId:String(E.organization_id),name:String(E.name),algorithm:"ed25519",publicKeyPem:String(E.public_key_pem),fingerprint:String(E.fingerprint),revokedAt:F_(E.revoked_at),createdAt:String(E.created_at)}),L5=(E)=>({id:String(E.id),organizationId:String(E.organization_id),version:String(E.version),channel:String(E.channel),publishedAt:String(E.published_at),keyId:String(E.key_id),digest:String(E.digest),document:Mh(E.document,{}),signature:String(E.signature),verificationStatus:String(E.verification_status),compatibility:Mh(E.compatibility,{compatible:!1,reasons:[]}),createdAt:String(E.created_at)}),t5=(E)=>({id:String(E.id),projectId:String(E.project_id),name:String(E.name),schedule:String(E.schedule),timezone:String(E.timezone),durationMinutes:Number(E.duration_minutes),allowedOperations:Mh(E.allowed_operations,[]),requireApproval:Number(E.require_approval)===1,enabled:Number(E.enabled)===1,createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),O5=(E)=>({id:String(E.id),projectId:String(E.project_id),manifestId:String(E.manifest_id),windowId:F_(E.window_id),fromVersion:String(E.from_version),strategy:String(E.strategy),batchSize:Number(E.batch_size),healthGate:Mh(E.health_gate,{}),status:String(E.status),currentStage:F_(E.current_stage),backupId:F_(E.backup_id),approvedBy:F_(E.approved_by),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),nX=(E)=>({id:String(E.id),campaignId:String(E.campaign_id),serverId:F_(E.server_id),target:String(E.target),cohort:Number(E.cohort),previousVersion:String(E.previous_version),status:String(E.status),evidence:Mh(E.evidence,{}),error:F_(E.error),startedAt:F_(E.started_at),finishedAt:F_(E.finished_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),U5=(E)=>({id:String(E.id),projectId:String(E.project_id),kind:String(E.kind),criteria:Mh(E.criteria,{}),candidates:Mh(E.candidates,[]),candidateDigest:String(E.candidate_digest),estimatedBytes:Number(E.estimated_bytes),status:String(E.status),confirmation:F_(E.confirmation),expiresAt:String(E.expires_at),result:Mh(E.result,{}),createdAt:String(E.created_at),updatedAt:String(E.updated_at)}),$5=(E)=>({id:String(E.id),projectId:String(E.project_id),backupPolicyId:F_(E.backup_policy_id),recoveryPointId:F_(E.recovery_point_id),topologyId:F_(E.topology_id),scenario:String(E.scenario),isolatedTarget:String(E.isolated_target),expectedRpoMinutes:Number(E.expected_rpo_minutes),expectedRtoMinutes:Number(E.expected_rto_minutes),status:String(E.status),operationId:F_(E.operation_id),evidence:Mh(E.evidence,{}),measuredRpoMinutes:E.measured_rpo_minutes==null?void 0:Number(E.measured_rpo_minutes),measuredRtoMinutes:E.measured_rto_minutes==null?void 0:Number(E.measured_rto_minutes),cleanupVerified:Number(E.cleanup_verified)===1,error:F_(E.error),startedAt:F_(E.started_at),finishedAt:F_(E.finished_at),createdAt:String(E.created_at),updatedAt:String(E.updated_at)});class st{control;now;id;constructor(E,T=()=>new Date,_=()=>crypto.randomUUID()){this.control=E;this.now=T;this.id=_}addTrustedKey(E){let T=this.id(),_=this.now().toISOString(),d=N5(E.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[T,E.organizationId,E.name,E.publicKeyPem,d,_]),this.key(T)}key(E){let T=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(E);return T?gb(T):void 0}revokeKey(E){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),E]),this.key(E)}importManifest(E){let T=this.key(E.keyId);if(!T||T.organizationId!==E.organizationId)throw Error("Trusted update key was not found.");if(T.revokedAt)throw Error("Update signing key is revoked.");if(!A5(E.document,E.signature,T.publicKeyPem))throw Error("Update manifest signature is invalid.");let _=S5(E.document,E.current),d=r5(E.document),R=this.id(),h=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[R,E.organizationId,E.document.version,E.document.channel,new Date(E.document.publishedAt).toISOString(),E.keyId,d,JSON.stringify(E.document),E.signature,JSON.stringify(_),h]),this.manifest(R)}manifest(E){let T=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(E);return T?L5(T):void 0}manifests(E){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(E).map(L5)}createWindow(E){let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[T,E.projectId,E.name,E.schedule,E.timezone,E.durationMinutes,JSON.stringify(E.allowedOperations),E.requireApproval===!1?0:1,_,_]),this.window(T)}window(E){let T=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(E);return T?t5(T):void 0}windows(E){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(E).map(t5)}createCampaign(E){return this.control.transaction(()=>{let T=this.manifest(E.manifestId);if(!T?.compatibility.compatible||T.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!E.backupId)throw Error("A verified pre-upgrade backup is required.");let _=this.id(),d=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[_,E.projectId,E.manifestId,E.windowId??null,E.fromVersion,E.strategy,E.batchSize,JSON.stringify(E.healthGate),E.backupId,E.approvedBy??null,d,d]),E.targets.forEach((R,h)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),_,R.serverId??null,R.target,E.strategy==="canary"?h===0?0:1+Math.floor((h-1)/E.batchSize):Math.floor(h/E.batchSize),R.previousVersion,d,d])),this.campaign(_)})}campaign(E){let T=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(E);return T?O5(T):void 0}campaigns(E){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(E).map(O5)}targets(E){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(E).map(nX)}updateCampaign(E,T){let _=this.campaign(E);if(!_)throw Error("Upgrade campaign was not found.");let d={..._,...T};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[d.status,d.currentStage??null,this.now().toISOString(),E]),this.campaign(E)}updateTarget(E,T){let _=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(E);if(!_)throw Error("Upgrade target was not found.");let d={...nX(_),...T};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.evidence),d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),E]),nX(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(E))}createCleanup(E){let T=[...E.candidates].sort((r,N)=>r.id.localeCompare(N.id)),_=q$(T),d=this.id(),R=this.now().toISOString(),h=new Date(this.now().getTime()+(E.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[d,E.projectId,E.kind,JSON.stringify(E.criteria),JSON.stringify(T),_,T.reduce((r,N)=>r+N.bytes,0),h,R,R]),this.cleanup(d)}cleanup(E){let T=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(E);return T?U5(T):void 0}cleanups(E){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(E).map(U5)}updateCleanup(E,T){let _=this.cleanup(E);if(!_)throw Error("Cleanup plan was not found.");let d={..._,...T};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[d.status,d.confirmation??null,JSON.stringify(d.result),this.now().toISOString(),E]),this.cleanup(E)}createDrill(E){if(!/^isolated:\/\//.test(E.isolatedTarget))throw Error("DR drills require an isolated target.");let T=this.id(),_=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[T,E.projectId,E.backupPolicyId??null,E.recoveryPointId??null,E.topologyId??null,E.scenario,E.isolatedTarget,E.expectedRpoMinutes,E.expectedRtoMinutes,_,_]),this.drill(T)}drill(E){let T=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(E);return T?$5(T):void 0}drills(E){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(E).map($5)}updateDrill(E,T){let _=this.drill(E);if(!_)throw Error("DR drill was not found.");let d={..._,...T};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,JSON.stringify(d.evidence),d.measuredRpoMinutes??null,d.measuredRtoMinutes??null,d.cleanupVerified?1:0,d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),E]),this.drill(E)}}function bb(E,T=new Date){if(!E.enabled)return!1;let _=new Date(E.schedule);if(!Number.isNaN(_.getTime()))return T>=_&&T.getTime()<=_.getTime()+E.durationMinutes*60000;let d=/^(\d{2}):(\d{2})$/.exec(E.schedule);if(!d)return!1;let R=new Intl.DateTimeFormat("en-US",{timeZone:E.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(T),h=Number(R.find((N)=>N.type==="hour")?.value)*60+Number(R.find((N)=>N.type==="minute")?.value),r=Number(d[1])*60+Number(d[2]);return h>=r&&h<r+E.durationMinutes}class pt{store;now;queue;constructor(E,T,_=()=>new Date){this.store=E;this.now=_;this.queue=T??new nE(E.control)}enqueueCampaign(E,T={}){let _=this.store.campaign(E);if(!_)throw Error("Upgrade campaign was not found.");let d=_.windowId?this.store.window(_.windowId):void 0;if(d&&!d.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(d&&!T.overrideWindow&&!bb(d,this.now()))throw Error("Upgrade is outside its maintenance window.");if(d?.requireApproval&&!T.approvedBy&&!_.approvedBy)throw Error("Maintenance approval is required.");let R=this.queue.enqueue({projectId:_.projectId,actorId:T.approvedBy,kind:"maintenance.upgrade",input:{campaignId:E},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(E,{status:"queued"}),operation:R}}async previewCleanup(E,T){let _=T.find((d)=>d.kind===E.kind);if(!_)throw Error(`No ${E.kind} cleanup driver is configured.`);return this.store.createCleanup({...E,candidates:await _.discover(E.criteria)})}enqueueCleanup(E,T){let _=this.store.cleanup(E);if(!_||_.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(_.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let d=`DELETE ${_.candidates.length} ${_.kind}`;if(T!==d)throw Error(`Exact confirmation ${d} is required.`);let R=this.queue.enqueue({projectId:_.projectId,kind:"maintenance.cleanup",input:{planId:E},lockKey:`cleanup:${_.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(E,{status:"approved",confirmation:T}),operation:R}}enqueueDrill(E){let T=this.store.drill(E);if(!T||T.status!=="planned")throw Error("A planned DR drill is required.");let _=this.queue.enqueue({projectId:T.projectId,kind:"maintenance.drill",input:{drillId:E},lockKey:`drill:${T.scenario}:${T.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(E,{status:"queued",operationId:_.id}),operation:_}}}var lX=(E)=>E&&typeof E==="object"&&!Array.isArray(E)?E:{};function D5(E){return{"maintenance.upgrade":async(R)=>{let h=E.store.campaign(String(lX(R.operation.input).campaignId??""));if(!h||!E.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let r=E.store.manifest(h.manifestId);if(!r?.compatibility.compatible||r.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let N=r.document.artifacts.find((S)=>S.platform===process.platform&&S.architecture===process.arch)??r.document.artifacts[0];if(!N)throw Error("No update artifact matches this platform.");E.store.updateCampaign(h.id,{status:"running",currentStage:"preflight"});let A=[];try{for(let S of[...new Set(E.store.targets(h.id).map((L)=>L.cohort))].sort((L,t)=>L-t)){E.store.updateCampaign(h.id,{currentStage:`cohort:${S}`});for(let L of E.store.targets(h.id).filter((t)=>t.cohort===S)){R.throwIfCancellationRequested(),R.checkpoint(`download:${L.target}`,"Downloading signed platform artifact."),E.store.updateTarget(L.id,{status:"downloading",startedAt:new Date().toISOString()});let t=await E.platform.download({target:L,artifact:N,signal:R.signal});if(t.sha256!==N.sha256)throw Error(`Artifact checksum mismatch for ${L.target}.`);R.checkpoint(`install:${L.target}`,"Installing verified artifact."),E.store.updateTarget(L.id,{status:"installing"}),await E.platform.install({target:L,path:t.path,version:r.version,signal:R.signal}),A.push(L);let O=await E.platform.health({target:L,gate:h.healthGate});if(!O.healthy)throw Error(`Upgrade health gate failed for ${L.target}.`);E.store.updateTarget(L.id,{status:"healthy",evidence:O.evidence,finishedAt:new Date().toISOString()})}}return E.store.updateCampaign(h.id,{status:"succeeded",currentStage:void 0}),{campaignId:h.id,version:r.version,targets:A.length}}catch(S){E.store.updateCampaign(h.id,{status:"rolling_back",currentStage:"rollback"});for(let L of A.reverse())E.store.updateTarget(L.id,{status:"rolling_back"}),await E.platform.rollback({target:L,version:L.previousVersion,signal:R.signal}),E.store.updateTarget(L.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw E.store.updateCampaign(h.id,{status:"rolled_back",currentStage:void 0}),S}},"maintenance.cleanup":async(R)=>{let h=E.store.cleanup(String(lX(R.operation.input).planId??""));if(!h||h.status!=="approved")throw Error("Approved cleanup plan was not found.");if(q$([...h.candidates].sort((L,t)=>L.id.localeCompare(t.id)))!==h.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let r=E.cleanup?.find((L)=>L.kind===h.kind);if(!r)throw Error(`No ${h.kind} cleanup driver is configured.`);E.store.updateCleanup(h.id,{status:"running"});let N=[],A=[];for(let L of h.candidates){R.throwIfCancellationRequested();try{await r.remove(L),N.push(L.id)}catch(t){A.push({id:L.id,error:t instanceof Error?t.message:String(t)})}}let S=A.length?N.length?"partial":"failed":"succeeded";if(E.store.updateCleanup(h.id,{status:S,result:{removed:N,failed:A,reclaimedBytes:h.candidates.filter((L)=>N.includes(L.id)).reduce((L,t)=>L+t.bytes,0)}}),A.length)throw Error(`Cleanup failed for ${A.length} candidate(s).`);return{planId:h.id,removed:N.length,reclaimedBytes:h.estimatedBytes}},"maintenance.drill":async(R)=>{let h=E.store.drill(String(lX(R.operation.input).drillId??""));if(!h)throw Error("DR drill was not found.");let r=E.recovery?.find((t)=>t.scenario===h.scenario);if(!r)throw Error(`No ${h.scenario} recovery driver is configured.`);let N=new Date;E.store.updateDrill(h.id,{status:"restoring",startedAt:N.toISOString()});let A=h.isolatedTarget,S={},L={};try{R.checkpoint("restore","Restoring into isolated drill target.");let t=await r.restore({drill:h,signal:R.signal});if(!t.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");A=t.target,S=t.evidence;let O=(N.getTime()-new Date(t.recoveryPointAt).getTime())/60000;E.store.updateDrill(h.id,{status:"verifying",measuredRpoMinutes:O,evidence:{restore:S}}),R.checkpoint("verify","Running recovery health checks without production traffic.");let U=await r.verify({drill:h,target:A});L=U.evidence;let D=(Date.now()-N.getTime())/60000;if(!U.healthy||O>h.expectedRpoMinutes||D>h.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");E.store.updateDrill(h.id,{measuredRpoMinutes:O,measuredRtoMinutes:D,evidence:{restore:S,verify:L}})}catch(t){throw E.store.updateDrill(h.id,{status:"failed",error:t instanceof Error?t.message:String(t),evidence:{restore:S,verify:L}}),t}finally{E.store.updateDrill(h.id,{status:"cleaning"});try{await r.cleanup({drill:h,target:A});let t=E.store.drill(h.id);E.store.updateDrill(h.id,{status:t.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(t){E.store.updateDrill(h.id,{status:"cleanup_required",cleanupVerified:!1,error:t instanceof Error?t.message:String(t),finishedAt:new Date().toISOString()})}}return{drillId:h.id,status:E.store.drill(h.id).status}}}}var I5={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class ot{kind;control;projectId;organizationId;constructor(E,T,_,d){this.kind=E;this.control=T;this.projectId=_;this.organizationId=d}async discover(E){let T=Math.max(1,Math.min(3650,Number(E.olderThanDays??30))),_=new Date(Date.now()-T*86400000).toISOString(),d=I5[this.kind],R=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(d.select).all(R,_).map((r)=>({id:String(r.id),kind:this.kind,label:`${this.kind}:${String(r.id)}`,bytes:Number(r.bytes??0),metadata:{createdAt:String(r.created_at)}}))}async remove(E){if(this.control.database.run(I5[this.kind].remove,[E.id]).changes!==1)throw Error(`${E.label} changed or is no longer removable.`)}}async function kb(){let E=await o(),T=lE(process.cwd(),E),_=new st(T.store),d=new pt(_),R=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((h)=>new ot(h,T.store,T.project.id,T.organization.id));return{controlPlane:T,store:_,service:d,cleanup:R}}async function Vh(E){let T=await kb();try{await E(T)}catch(_){Q(_ instanceof Error?_.message:String(_)),process.exitCode=1}finally{T.controlPlane.store.close()}}function iX(E){E.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(T)=>Vh((_)=>{let d={manifests:_.store.manifests(_.controlPlane.organization.id),windows:_.store.windows(_.controlPlane.project.id),campaigns:_.store.campaigns(_.controlPlane.project.id),cleanups:_.store.cleanups(_.controlPlane.project.id),drills:_.store.drills(_.controlPlane.project.id)},R=[...d.manifests.map((h)=>["update",h.version,h.compatibility.compatible?"compatible":"blocked",h.compatibility.reasons.join("; ")||h.channel]),...d.campaigns.map((h)=>["upgrade",h.id,h.status,h.currentStage??h.fromVersion]),...d.cleanups.map((h)=>["cleanup",h.kind,h.status,`${h.candidates.length} items / ${h.estimatedBytes} bytes`]),...d.drills.map((h)=>["DR drill",h.scenario,h.status,h.isolatedTarget])];if(T.json)console.log(JSON.stringify(d,null,2));else EE(["Area","Name / version","Status","Detail"],R)})),E.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(T,_)=>Vh(async(d)=>{let R=d.store.addTrustedKey({organizationId:d.controlPlane.organization.id,name:T,publicKeyPem:await Bun.file(_).text()});Z(`Trusted ${R.name}: ${R.fingerprint}`)})),E.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(T,_,d)=>Vh(async(R)=>{let h=await Bun.file(T).json(),r=(await Bun.file(_).text()).trim(),N=R.store.importManifest({organizationId:R.controlPlane.organization.id,keyId:d,document:h,signature:r,current:{schemaVersion:R.controlPlane.store.health().schemaVersion,currentVersion:mt,platform:process.platform,architecture:process.arch}});Z(`Verified ${N.version}; ${N.compatibility.compatible?"compatible":"blocked: "+N.compatibility.reasons.join("; ")}`)})),E.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,_,d)=>Vh((R)=>{let h=R.store.createWindow({projectId:R.controlPlane.project.id,name:T,schedule:_,timezone:d.timezone,durationMinutes:Number(d.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});Z(`Created ${h.name} (${h.id}).`)})),E.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,_,d)=>Vh((R)=>{let h=new nR(R.controlPlane.store).list(R.controlPlane.project.id).filter((A)=>A.status==="ready").map((A)=>({serverId:A.id,target:A.name,previousVersion:A.bootstrapVersion??mt}));if(!h.length)h.push({target:"control-plane",previousVersion:mt});let r=R.store.createCampaign({projectId:R.controlPlane.project.id,manifestId:T,fromVersion:mt,strategy:d.strategy==="rolling"?"rolling":"canary",batchSize:Number(d.batch),healthGate:{kind:"platform"},backupId:_,targets:h}),N=R.service.enqueueCampaign(r.id);Z(`Staged upgrade queued: ${N.operation.id}`)})),E.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(T,_)=>Vh(async(d)=>{let R=await d.service.previewCleanup({projectId:d.controlPlane.project.id,kind:T,criteria:{olderThanDays:Number(_.olderThan)}},d.cleanup);EE(["ID","Candidate","Bytes"],R.candidates.map((h)=>[h.id,h.label,String(h.bytes)])),$(`Apply with: cloud cleanup:apply ${R.id} --confirm "DELETE ${R.candidates.length} ${R.kind}"`)})),E.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(T,_)=>Vh((d)=>{let R=d.service.enqueueCleanup(T,String(_.confirm??""));Z(`Cleanup queued: ${R.operation.id}`)})),E.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,_,d)=>Vh((R)=>{let h=R.store.createDrill({projectId:R.controlPlane.project.id,scenario:T,isolatedTarget:_,expectedRpoMinutes:Number(d.rpo),expectedRtoMinutes:Number(d.rto),recoveryPointId:d.recoveryPoint,topologyId:d.topology});Z(`Planned isolated drill ${h.id}.`)})),E.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(T)=>Vh((_)=>{let d=_.service.enqueueDrill(T);Z(`DR drill queued: ${d.operation.id}`)}))}ME();xr();Bd();async function mX(){try{return(await o()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function aX(E){E.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(T)=>{b("Lambda Functions");let _=T?.region||await mX(),d=new jT(_);try{let{Functions:R=[]}=await d.listFunctions({MaxItems:50});if(!R.length){$("No functions found");return}EE(["Name","Runtime","Memory","Timeout","Last Modified"],R.map((h)=>[h.FunctionName??"-",h.Runtime??"-",h.MemorySize?`${h.MemorySize} MB`:"-",h.Timeout?`${h.Timeout}s`:"-",h.LastModified??"-"]))}catch(R){Q(`Failed to list functions: ${R.message}`),process.exitCode=1}}),E.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,_)=>{b(`Invoking ${T}`);let d=_?.region||await mX(),R=new jT(d),h=new n("Invoking function...");h.start();try{let r=await R.invoke({FunctionName:T,InvocationType:_?.async?"Event":"RequestResponse",Payload:_?.payload||"{}",LogType:_?.async?"None":"Tail"});if(r.FunctionError){if(h.fail(`Function returned an error (${r.FunctionError})`),r.Payload)$(r.Payload);process.exitCode=1;return}if(h.succeed(`Invoked (status ${r.StatusCode})`),r.Payload)$(`
9613
9613
  Response:`),$(r.Payload);if(r.LogResult)$(`
9614
9614
  Logs:`),$(Buffer.from(r.LogResult,"base64").toString("utf-8"))}catch(r){h.fail(`Invocation failed: ${r.message}`),process.exitCode=1}}),E.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,_)=>{b(`Logs for ${T}`);let d=_?.region||await mX(),R=new Sd(d),h=T.startsWith("/aws/lambda/")?T:`/aws/lambda/${T}`,r=Number(_?.since??15),N=(A)=>{for(let S of A){let L=S.timestamp?new Date(S.timestamp).toISOString():"";$(`${L} ${(S.message??"").trimEnd()}`)}};try{let A=Date.now()-r*60000,{events:S=[]}=await R.filterLogEvents({logGroupName:h,startTime:A,filterPattern:_?.filter,limit:200});if(N(S),S.length)A=(S[S.length-1].timestamp??A)+1;if(_?.tail){$(`
9615
9615
  (streaming — Ctrl+C to stop)`);for(;;){await new Promise((t)=>setTimeout(t,3000));let{events:L=[]}=await R.filterLogEvents({logGroupName:h,startTime:A,filterPattern:_?.filter,limit:200});if(L.length)N(L),A=(L[L.length-1].timestamp??A)+1}}}catch(A){Q(`Failed to read logs: ${A.message}`),process.exitCode=1}})}ME();async function w5(E){let T=Bun.spawn(["docker",...E],{stdin:"inherit",stdout:"inherit",stderr:"pipe"}),[_,d]=await Promise.all([T.exited,new Response(T.stderr).text()]);return{ok:_===0,exitCode:_,command:["docker",...E].join(" "),stderr:d.trim()}}function sX(E){E.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 _=["build","--file",T.file??"Dockerfile","--tag",T.tag??"latest","."];if(T.dryRun){console.log(`docker ${_.join(" ")}`);return}let d=await w5(_);if(T.json)console.log(JSON.stringify(d));if(!d.ok)Q(d.stderr||`docker exited ${d.exitCode}`),process.exitCode=d.exitCode;else Z(`Built ${T.tag??"latest"}.`)}),E.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){Q("--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 _=await w5(["push",T.image]);if(T.json)console.log(JSON.stringify(_));if(!_.ok)Q(_.stderr),process.exitCode=_.exitCode;else Z(`Pushed ${T.image}.`)}),E.command("container:deploy","Deploy a container image").action(async()=>ld("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."}))}ME();Bh();gR();function pX(E){E.command("domain:list","List all domains").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(T)=>{b("Domains");try{let _=bR(T?.provider),d=jd(T?.provider)?.provider||"unknown",R=new n(`Fetching domains from ${d}...`);R.start();let h=await _.listDomains();if(R.succeed(`Found ${h.length} domain(s)`),h.length===0){$("No domains found in this provider");return}let r=h.map((N)=>[N,"Active","-",d.charAt(0).toUpperCase()+d.slice(1)]);EE(["Domain","Status","SSL","Provider"],r)}catch(_){Q(`Failed to list domains: ${_ instanceof Error?_.message:String(_)}`)}}),E.command("domain:add <domain>","Add a new domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(T,_)=>{b(`Adding Domain: ${T}`);try{let d=bR(_?.provider),R=jd(_?.provider)?.provider||"unknown",h=new n(`Checking if ${R} can manage ${T}...`);if(h.start(),await d.canManageDomain(T))h.succeed(`Domain ${T} is already available in ${R}`),$(`
@@ -9709,7 +9709,7 @@ Invalidation is in progress. Use --wait to wait for completion.`)}catch(_){Q(`In
9709
9709
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[_,E.organizationId,E.projectId,E.environmentId??null,E.releaseId,E.kind,E.format,E.digest,zR(E.summary),E.content??null,E.sensitive?1:0,d]),this.controlPlane.appendEvent({organizationId:E.organizationId,projectId:E.projectId,type:"security.release_artifact.created",payload:{artifactId:_,releaseId:E.releaseId,kind:E.kind,format:E.format,digest:E.digest,sensitive:E.sensitive}}),lJ(this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE id = ?").get(_))}listReleaseArtifacts(E,T=!1){return this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE release_id = ? ORDER BY created_at, kind").all(E).map(lJ).map((_)=>_.sensitive&&!T?{..._,content:void 0}:_)}summary(E,T,_){let d=this.listFindings({organizationId:E,projectId:T,environmentId:_,limit:1000}),R=this.listScanRuns({organizationId:E,projectId:T,environmentId:_,limit:1000}),h={info:0,low:0,medium:0,high:0,critical:0};for(let N of d)if(N.status==="open"||N.status==="acknowledged")h[N.severity]++;let r={passed:0,failed:0,skipped:0,unavailable:0,unsupported:0,stale:0};for(let N of R)r[N.status]++;return{open:h,waived:d.filter((N)=>N.status==="waived").length,resolved:d.filter((N)=>N.status==="resolved").length,checks:r,lastScannedAt:R[0]?.completedAt}}exportPosture(E){let T=this.controlPlane.listProjects().filter((_)=>_.organizationId===E);return xE({format:"ts-cloud-security-posture",version:1,exportedAt:this.now(),organizationId:E,policies:this.listPolicies(E),findings:this.listFindings({organizationId:E,limit:1000}),waivers:this.listWaivers().filter((_)=>this.getFinding(_.findingId)?.organizationId===E),scans:T.flatMap((_)=>this.listScanRuns({organizationId:E,projectId:_.id,limit:1000})),decisions:T.flatMap((_)=>this.controlPlane.listEnvironments(_.id).flatMap((d)=>this.listDecisions(d.id,1000)))})}}yA();NA();import{existsSync as Fn,readdirSync as zn,readFileSync as jn,statSync as Bn}from"node:fs";import{extname as Wn,join as Hn,relative as yn}from"node:path";var $G=[{name:"AWS Access Key ID",pattern:/(?:^|[^A-Z0-9])((AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Z0-9]|$)/g,severity:"critical",description:"AWS Access Key ID detected"},{name:"AWS Secret Access Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key|secretAccessKey)['"]?\s*[=:]\s*['"]?([A-Za-z0-9/+=]{40})['"]?/gi,severity:"critical",description:"AWS Secret Access Key detected"},{name:"AWS Secret Key (Generic)",pattern:/(?:^|['"`:=\s])([A-Za-z0-9/+=]{40})(?:['"`\s]|$)/g,severity:"high",description:"Potential AWS Secret Key (40-char base64)"},{name:"Generic API Key",pattern:/(?:api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9_\-]{20,})['"]?/gi,severity:"high",description:"Generic API key detected"},{name:"RSA Private Key",pattern:/-----BEGIN RSA PRIVATE KEY-----/g,severity:"critical",description:"RSA private key detected"},{name:"OpenSSH Private Key",pattern:/-----BEGIN OPENSSH PRIVATE KEY-----/g,severity:"critical",description:"OpenSSH private key detected"},{name:"EC Private Key",pattern:/-----BEGIN EC PRIVATE KEY-----/g,severity:"critical",description:"EC private key detected"},{name:"PGP Private Key",pattern:/-----BEGIN PGP PRIVATE KEY BLOCK-----/g,severity:"critical",description:"PGP private key detected"},{name:"GitHub Token",pattern:/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/g,severity:"critical",description:"GitHub personal access token detected"},{name:"GitHub OAuth",pattern:/github[_-]?oauth[_-]?token\s*[=:]\s*['"]?([A-Za-z0-9_]{40})['"]?/gi,severity:"critical",description:"GitHub OAuth token detected"},{name:"Slack Token",pattern:/xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,severity:"critical",description:"Slack token detected"},{name:"Slack Webhook",pattern:/https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g,severity:"high",description:"Slack webhook URL detected"},{name:"Discord Webhook",pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/[0-9]+\/[A-Za-z0-9_-]+/g,severity:"high",description:"Discord webhook URL detected"},{name:"JWT Token",pattern:/eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*/g,severity:"high",description:"JWT token detected"},{name:"Google API Key",pattern:/AIza[0-9A-Za-z_-]{35}/g,severity:"critical",description:"Google API key detected"},{name:"Google OAuth ID",pattern:/[0-9]+-[A-Za-z0-9_]{32}\.apps\.googleusercontent\.com/g,severity:"high",description:"Google OAuth client ID detected"},{name:"Firebase API Key",pattern:/(?:firebase[_-]?api[_-]?key)\s*[=:]\s*['"]?([A-Za-z0-9_-]{39})['"]?/gi,severity:"critical",description:"Firebase API key detected"},{name:"Cloudflare API Token",pattern:/(?:cloudflare[_-]?api[_-]?token|cf[_-]?api[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{40})['"]?/gi,severity:"critical",description:"Cloudflare API token detected"},{name:"Azure Client Secret",pattern:/(?:azure[_-]?client[_-]?secret|client[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9~._-]{34,})['"]?/gi,severity:"critical",description:"Azure client secret detected"},{name:"Heroku API Key",pattern:/(?:heroku[_-]?api[_-]?key)\s*[=:]\s*['"]?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})['"]?/gi,severity:"critical",description:"Heroku API key detected"},{name:"Database Connection String",pattern:/(?:mysql|postgres|postgresql|mongodb|redis|mongodb\+srv):\/\/[^:]+:[^@]+@[^/\s]+/gi,severity:"critical",description:"Database connection string with credentials detected"},{name:"Database Password",pattern:/(?:db[_-]?password|database[_-]?password|mysql[_-]?password|postgres[_-]?password)\s*[=:]\s*['"]?([^'"\s]{8,})['"]?/gi,severity:"critical",description:"Database password detected"},{name:"Stripe API Key",pattern:/(?:sk|pk)_(?:test|live)_[0-9a-zA-Z]{24,}/g,severity:"critical",description:"Stripe API key detected"},{name:"PayPal Client ID",pattern:/(?:paypal[_-]?client[_-]?id)\s*[=:]\s*['"]?([A-Za-z0-9_-]{80})['"]?/gi,severity:"high",description:"PayPal client ID detected"},{name:"Square Access Token",pattern:/sq0[a-z]{3}-[0-9A-Za-z_-]{22,}/g,severity:"critical",description:"Square access token detected"},{name:"Twilio API Key",pattern:/SK[a-f0-9]{32}/g,severity:"critical",description:"Twilio API key detected"},{name:"SendGrid API Key",pattern:/SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/g,severity:"critical",description:"SendGrid API key detected"},{name:"Mailgun API Key",pattern:/key-[0-9a-zA-Z]{32}/g,severity:"critical",description:"Mailgun API key detected"},{name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"]([^'"]{8,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded password detected"},{name:"Secret/Token Assignment",pattern:/(?:secret|token|auth[_-]?token|access[_-]?token)\s*[=:]\s*['"]([A-Za-z0-9_\-/+=]{16,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded secret or token detected"},{name:"NPM Token",pattern:/(?:npm[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{36})['"]?/gi,severity:"critical",description:"NPM token detected"},{name:"SSH Private Key Path Exposed",pattern:/~\/\.ssh\/id_[a-z]+|\/home\/[^/]+\/\.ssh\/id_[a-z]+/g,severity:"medium",description:"SSH private key path exposed"},{name:"Env Variable with Secret",pattern:/(?:process\.env\.)((?=[A-Z_]*(?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL|AUTH))[A-Z_]+)\s*(?:===?\s*['"]([^'"]+)['"])?/g,severity:"medium",description:"Environment variable containing secret may be exposed"}],Yn=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],en=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt","framework.bak","pantry",".pantry","tests","test","__tests__","spec","__mocks__",".github",".gitlab",".circleci"],Gn=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","bun.lock","*.min.js","*.min.css","*.map","*.d.ts","*.test.ts","*.test.js","*.spec.ts","*.spec.js",".env",".env.*"];class dL{patterns;excludeDirs;excludeFiles;maxFileSize;constructor(E){this.patterns=[...$G,...E?.customPatterns||[]],this.excludeDirs=[...en,...E?.excludeDirs||[]],this.excludeFiles=[...Gn,...E?.excludeFiles||[]],this.maxFileSize=E?.maxFileSize||1048576}async scan(E){let T=Date.now(),_=[],d=0,{directory:R,exclude:h=[],include:r,skipPatterns:N=[]}=E,A=E.failOnSeverity||"critical";if(!Fn(R))throw Error(`Directory not found: ${R}`);let S=this.getFilesToScan(R,[...this.excludeDirs,...h],r);for(let D of S){let C=yn(R,D);if(this.shouldExcludeFile(C))continue;try{if(Bn(D).size>this.maxFileSize)continue;let c=jn(D,"utf-8"),z=this.scanContent(c,C,N);_.push(...z),d++}catch{continue}}let L={critical:_.filter((D)=>D.pattern.severity==="critical").length,high:_.filter((D)=>D.pattern.severity==="high").length,medium:_.filter((D)=>D.pattern.severity==="medium").length,low:_.filter((D)=>D.pattern.severity==="low").length},t=["low","medium","high","critical"],O=t.indexOf(A),U=!0;for(let D=O;D<t.length;D++)if(L[t[D]]>0){U=!1;break}return{passed:U,findings:_,scannedFiles:d,duration:Date.now()-T,summary:L}}scanContent(E,T,_){let d=[],R=E.split(`
9710
9710
  `);for(let h of this.patterns){if(_.includes(h.name))continue;h.pattern.lastIndex=0;let r;while((r=h.pattern.exec(E))!==null){let N=E.substring(0,r.index),A=N.split(`
9711
9711
  `).length,S=N.lastIndexOf(`
9712
- `),L=r.index-S,t=R[A-1]||"";if(this.isLikelyPlaceholder(r[0],t))continue;let O=r[1]||r[0];if(h.name==="AWS Secret Key (Generic)"&&/^[a-f0-9]{40}$/i.test(O))continue;if(h.name==="AWS Secret Key (Generic)"&&!this.hasSecretCharacterDiversity(O))continue;if(h.name==="AWS Secret Key (Generic)"&&/^(?:Actions|Commands|Controllers|Handlers|Jobs|Listeners|Middleware|Models|Resources|Services)\//.test(O))continue;if(this.isLowEntropy(O))continue;d.push({file:T,line:A,column:L,match:this.maskSecret(r[0]),pattern:h,context:this.maskSecret(t.trim())})}}return d}isLikelyPlaceholder(E,T){let _=["example","placeholder","your_","YOUR_","xxx","XXX","***","test","TEST","dummy","DUMMY","fake","FAKE","sample","SAMPLE","<your","${","{{","process.env","import.meta.env","CHANGEME","TODO","FIXME"],d=E.toLowerCase(),R=T.toLowerCase();for(let r of _)if(d.includes(r.toLowerCase())||R.includes(r.toLowerCase()))return!0;let h=T.trim();if(h.startsWith("//")||h.startsWith("#")||h.startsWith("*")||h.startsWith("/*")){if(R.includes("example")||R.includes("format:")||R.includes("e.g."))return!0}return!1}isLowEntropy(E){if(E.length<8)return!1;if(new Set(E).size<8)return!0;if(/(.)\1{3,}/.test(E))return!0;return!1}hasSecretCharacterDiversity(E){return[/[a-z]/.test(E),/[A-Z]/.test(E),/\d/.test(E),/[/+=]/.test(E)].filter(Boolean).length>=3}maskSecret(E){if(E.length<=8)return"*".repeat(E.length);let T=Math.min(4,Math.floor(E.length*0.2));return E.substring(0,T)+"*".repeat(E.length-T*2)+E.substring(E.length-T)}getFilesToScan(E,T,_){let d=[],R=_||Yn,h=(r)=>{let N=zn(r,{withFileTypes:!0});for(let A of N){let S=Hn(r,A.name);if(A.isDirectory()){if(!T.includes(A.name))h(S)}else if(A.isFile()){let L=Wn(A.name).toLowerCase();if(R.includes(L)||A.name.startsWith(".env")||A.name.endsWith(".config"))d.push(S)}}};return h(E),d}shouldExcludeFile(E){let T=E.split("/").pop()||"";for(let _ of this.excludeFiles)if(_.startsWith("*")){let d=_.substring(1);if(T.endsWith(d))return!0}else if(_.endsWith("*")){let d=_.substring(0,_.length-1);if(T.startsWith(d))return!0}else if(T===_)return!0;return!1}addPattern(E){this.patterns.push(E)}getPatterns(){return[...this.patterns]}}function Qn(E,T){return{status:"unavailable",findings:[],error:`${E.id} exceeded its ${T}ms timeout`,metadata:{timeoutMs:T}}}class AA{posture;defaultTimeoutMs;nowFn;constructor(E,T={}){this.posture=E;this.defaultTimeoutMs=T.defaultTimeoutMs??60000,this.nowFn=T.now??(()=>new Date)}async run(E,T){let _=this.nowFn(),d=Math.max(100,E.timeoutMs??this.defaultTimeoutMs),R=new AbortController,h,r=new Promise((L)=>{h=setTimeout(()=>{R.abort(),L(Qn(E,d))},d)}),N;try{N=await Promise.race([E.scan({...T,signal:R.signal}),r])}catch(L){N={status:"unavailable",findings:[],error:L instanceof Error?L.message:String(L)}}finally{if(h)clearTimeout(h)}let A=this.nowFn(),S={...T,scannerId:E.id,scannerVersion:E.version,status:N.status,findings:N.findings,metadata:N.metadata,error:N.error,startedAt:_.toISOString(),completedAt:A.toISOString(),durationMs:Math.max(0,A.getTime()-_.getTime())};return this.posture.recordScan(S)}async runAll(E,T){return Promise.all(E.map((_)=>this.run(_,T)))}}class n0{scanner;id="source-secrets";version="1.0.0";timeoutMs=30000;constructor(E=new dL){this.scanner=E}async scan(E){if(!E.artifactRoot)return{status:"skipped",findings:[],error:"No artifact root was supplied"};let T=await this.scanner.scan({directory:E.artifactRoot,failOnSeverity:"critical"});return{status:T.passed?"passed":"failed",findings:T.findings.map((_)=>({...E,ruleId:_.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:_.pattern.severity,title:_.pattern.name,description:_.pattern.description,subject:`${_.file}:${_.line}`,evidence:{file:_.file,line:_.line,column:_.column,match:_.match,context:_.context},remediation:"Remove the credential, rotate it at its issuer, and use a managed secret or environment reference."})),metadata:{scannedFiles:T.scannedFiles,summary:T.summary}}}}function Mn(E){let T=E?.toLowerCase();return T==="critical"||T==="high"||T==="medium"||T==="low"?T:"info"}class aJ{id="trivy-image";version;timeoutMs;constructor(E={}){this.version=E.version??"local",this.timeoutMs=E.timeoutMs??120000,this.executable=E.executable??"trivy"}executable;async scan(E){if(!E.imageRef)return{status:"skipped",findings:[],error:"No image reference was supplied"};let T;try{T=Bun.spawn([this.executable,"image","--format","json","--quiet","--scanners","vuln",E.imageRef],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",TRIVY_NO_PROGRESS:"true"}})}catch(A){return{status:"unsupported",findings:[],error:A instanceof Error?A.message:String(A)}}let _=()=>T.kill();E.signal.addEventListener("abort",_,{once:!0});let[d,R,h]=await Promise.all([T.exited,new Response(T.stdout).text(),new Response(T.stderr).text()]);if(E.signal.removeEventListener("abort",_),d!==0)return{status:/not found|enoent/i.test(h)?"unsupported":"unavailable",findings:[],error:h.slice(0,2000)||`Trivy exited with ${d}`};let r=JSON.parse(R),N=[];for(let A of r.Results??[])for(let S of A.Vulnerabilities??[]){let L=S.VulnerabilityID??"unknown-vulnerability";N.push({...E,ruleId:L,severity:Mn(S.Severity),title:S.Title||L,description:S.Description||`${L} affects ${S.PkgName??"an image package"}.`,subject:`${E.imageRef}:${S.PkgName??"unknown"}:${S.InstalledVersion??"unknown"}`,evidence:{image:E.imageRef,target:A.Target??"",cve:L,package:S.PkgName??"",installedVersion:S.InstalledVersion??"",fixedVersion:S.FixedVersion??"",reference:S.PrimaryURL??""},remediation:S.FixedVersion?`Upgrade ${S.PkgName} to ${S.FixedVersion} or later.`:"Remove or replace the affected package and rescan the image."})}return{status:N.length?"failed":"passed",findings:N,metadata:{imageRef:E.imageRef,vulnerabilityCount:N.length,localOnly:!0}}}}import{createHash as Vn,createVerify as h$E}from"node:crypto";import{existsSync as Kn,readFileSync as fn}from"node:fs";import{basename as Pn,join as Zn,resolve as DG}from"node:path";function l0(E){return Vn("sha256").update(E).digest("hex")}function qn(E){let T=[["dependencies","required"],["optionalDependencies","optional"],["devDependencies","excluded"],["peerDependencies","required"]],_=new Map;for(let[d,R]of T){let h=E[d];if(!h||typeof h!=="object"||Array.isArray(h))continue;for(let[r,N]of Object.entries(h)){let A=String(N).replace(/^[~^]/,""),S=`${r}@${A}`;if(!_.has(S))_.set(S,{type:"library",name:r,version:A,purl:`pkg:npm/${encodeURIComponent(r)}@${encodeURIComponent(A)}`,scope:R})}}return[..._.values()].sort((d,R)=>`${d.name}@${d.version}`.localeCompare(`${R.name}@${R.version}`))}function IG(E,T={}){let _=Zn(DG(E),"package.json");if(!Kn(_))throw Error(`Cannot generate an SBOM: ${_} was not found`);let d=fn(_,"utf8"),R=JSON.parse(d),h=String(R.name??Pn(DG(E))),r=String(R.version??"0.0.0"),N=l0(d);return{bomFormat:"CycloneDX",specVersion:"1.5",serialNumber:T.serial??`urn:uuid:${crypto.randomUUID()}`,version:1,metadata:{timestamp:(T.now??new Date).toISOString(),component:{type:"application",name:h,version:r,purl:`pkg:npm/${encodeURIComponent(h)}@${encodeURIComponent(r)}`,hashes:[{alg:"SHA-256",content:N}]},tools:[{vendor:"ts-cloud",name:"security-posture",version:"1.0.0"}]},components:qn(R)}}async function CG(E,T={}){let _=Bun.spawn([T.executable??"syft",E,"-o","cyclonedx-json"],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",SYFT_CHECK_FOR_APP_UPDATE:"false"}}),d=()=>_.kill();T.signal?.addEventListener("abort",d,{once:!0});let[R,h,r]=await Promise.all([_.exited,new Response(_.stdout).text(),new Response(_.stderr).text()]);if(T.signal?.removeEventListener("abort",d),R!==0)throw Error(r.slice(0,2000)||`Syft exited with ${R}`);return JSON.parse(h)}function sJ(E,T,_){let d=JSON.stringify(_);return E.addReleaseArtifact({...T,kind:"sbom",format:`cyclonedx-${_.specVersion}+json`,digest:`sha256:${l0(d)}`,summary:{component:_.metadata.component.name,version:_.metadata.component.version,components:_.components.length},content:d,sensitive:!0})}function wG(E,T,_){let d={total:_.length,critical:0,high:0,medium:0,low:0,info:0,fixable:0};for(let h of _){d[h.severity]++;let r=h.evidence;if(typeof r.fixedVersion==="string"&&r.fixedVersion)d.fixable++}let R=JSON.stringify({releaseId:T.releaseId,generatedAt:new Date().toISOString(),findings:_.map((h)=>({id:h.id,ruleId:h.ruleId,severity:h.severity,subject:h.subject,remediation:h.remediation}))});return E.addReleaseArtifact({...T,kind:"vulnerability_summary",format:"ts-cloud-vulnerability-summary+json",digest:`sha256:${l0(R)}`,summary:d,content:R,sensitive:!0})}function cG(E){if(!E.artifact&&!E.artifactSha256)throw Error("Release provenance requires artifact content or a SHA-256 digest");return{_type:"https://in-toto.io/Statement/v1",subject:[{name:E.artifactName,digest:{sha256:E.artifactSha256?.replace(/^sha256:/,"")??l0(E.artifact)}}],predicateType:"https://slsa.dev/provenance/v1",predicate:{buildDefinition:{buildType:"https://ts-cloud.dev/build/v1",externalParameters:E.externalParameters??{},internalParameters:{},resolvedDependencies:E.resolvedDependencies??[]},runDetails:{builder:{id:"https://ts-cloud.dev/builders/local/v1"},metadata:{invocationId:E.invocationId,startedOn:E.startedAt,finishedOn:E.completedAt}}}}}function XG(E,T,_){let d=JSON.stringify(_);return E.addReleaseArtifact({...T,kind:"provenance",format:"in-toto+slsa-v1+json",digest:`sha256:${l0(d)}`,summary:{subjects:_.subject.length,builder:_.predicate.runDetails.builder.id,buildType:_.predicate.buildDefinition.buildType},content:d,sensitive:!0})}function $d(E,T){let _=E.environments.get(T);if(!_)throw Error(`Security scope for environment '${T}' was not found`);return{organizationId:E.organization.id,projectId:E.project.id,environmentId:_.id}}function i0(E,T){let _=new EN(E.store),d=_.listPolicies(E.organization.id);for(let[R,h]of E.environments){if(d.some((N)=>N.environmentId===h.id))continue;let r=R==="production"||h.kind==="production";d.push(_.createPolicy({organizationId:E.organization.id,environmentId:h.id,name:r?"Production baseline":"Environment baseline",scannerFailMode:r?"closed":"open",requiredScanners:["source-secrets"],rules:r?[{minimumSeverity:"critical",action:"block"},{minimumSeverity:"high",action:"block"},{minimumSeverity:"medium",action:"warn"},{minimumSeverity:"low",action:"record"}]:[{minimumSeverity:"critical",action:"warn"},{minimumSeverity:"high",action:"warn"},{minimumSeverity:"low",action:"record"}],actorId:T}))}return d}function JG(E,T,_,d={}){let R=_.findings.map((h)=>({...T,ruleId:h.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:h.pattern.severity,title:h.pattern.name,description:h.pattern.description,subject:`${h.file}:${h.line}`,evidence:{file:h.file,line:h.line,column:h.column,match:h.match,context:h.context},remediation:"Remove and rotate the credential, then reference it through a managed secret or environment variable."}));return E.recordScan({...T,scannerId:"source-secrets",scannerVersion:d.scannerVersion??"1.0.0",status:d.skipped?"skipped":_.passed?"passed":"failed",findings:d.skipped?[]:R,metadata:{scannedFiles:_.scannedFiles,durationMs:_.duration,summary:_.summary},durationMs:_.duration,error:d.skipped?"The operator explicitly skipped source-secret scanning.":void 0})}function FG(E,T,_="The operator explicitly skipped source-secret scanning."){return E.recordScan({...T,scannerId:"source-secrets",scannerVersion:"1.0.0",status:"skipped",findings:[],error:_})}function xn(E,T){let _=[],d=T.security;if(d?.firewall&&!["active","configured","ok"].includes(String(d.firewall.status)))_.push({...E,ruleId:"host-firewall-disabled",severity:"high",title:"Host firewall is not active",description:String(d.firewall.summary??"The host firewall did not report an active configuration."),subject:"host:firewall",evidence:{status:String(d.firewall.status??"unknown"),rules:Array.isArray(d.firewall.rules)?d.firewall.rules.length:0},remediation:"Apply the declarative firewall policy and confirm only required listeners are public."});for(let R of d?.ports??[]){let h=String(R.listen??""),r=Number(h.match(/:(\d+)$/)?.[1]);if(R.exposure==="public"&&Number.isFinite(r)&&![22,80,443].includes(r))_.push({...E,ruleId:"unexpected-public-listener",severity:"medium",title:`Unexpected public listener on port ${r}`,description:`${String(R.processName??"A process")} is listening publicly outside the standard SSH/HTTP/HTTPS ports.`,subject:`host:port:${r}`,evidence:{protocol:String(R.proto??""),listen:h,process:String(R.processName??"")},remediation:"Bind the service to loopback/private networking or explicitly document and firewall the required public port."})}for(let R of d?.tlsCertificates??[]){let h=Number(R.daysRemaining);if(Number.isFinite(h)&&h<30)_.push({...E,ruleId:"tls-certificate-expiry",severity:h<14?"high":"medium",title:`TLS certificate expires in ${h} days`,description:`${String(R.domain??"A configured domain")} needs renewal.`,subject:`tls:${String(R.domain??"unknown")}`,evidence:{domain:String(R.domain??""),daysRemaining:h,expires:String(R.expires??"")},remediation:"Renew the certificate and verify automatic renewal can complete before expiry."})}for(let R of T.diagnostics??[]){if(R.status==="pass"||R.status==="ok")continue;_.push({...E,ruleId:`diagnostic-${String(R.name??"unknown").toLowerCase().replace(/[^a-z0-9]+/g,"-")}`,severity:R.status==="fail"?"high":"medium",title:String(R.name??"Host security check"),description:String(R.detail??"The host security diagnostic did not pass."),subject:`diagnostic:${String(R.name??"unknown")}`,evidence:{status:String(R.status??"unknown")},remediation:"Follow the diagnostic guidance, rerun the check, and confirm the finding resolves."})}return _}function ZD(E,T,_){let d=!!_.security||Array.isArray(_.diagnostics),R=d?xn(T,_):[];return E.recordScan({...T,scannerId:"host-posture",scannerVersion:"1.0.0",status:!d?"unavailable":R.length?"failed":"passed",findings:R,metadata:{source:"dashboard-live-probe",checks:Array.isArray(_.diagnostics)?_.diagnostics.length:0},error:d?void 0:"Live host posture data was unavailable; source and provider checks remain usable."})}function SA(E,T){let _=E.evaluateGate({...T.scope,operationId:T.operationId}),d=E.listFindings({...T.scope,limit:1000}).filter((R)=>R.status!=="resolved");return{decision:_,summary:{desiredConfigHash:T.desiredConfigHash??null,securityImpact:{critical:d.filter((R)=>R.severity==="critical").length,high:d.filter((R)=>R.severity==="high").length,waived:d.filter((R)=>R.status==="waived").length,assigned:d.filter((R)=>!!R.ownerActorId).length},blockingFindingIds:_.findingIds,policy:{id:_.policyId,version:_.policyVersion},scannerVersions:_.scannerVersions}}}async function zG(E,T){let _=T.scanner??new aJ({timeoutMs:T.scannerTimeoutMs}),R=await new AA(E,{defaultTimeoutMs:T.scannerTimeoutMs??120000}).run(_,{...T.scope,releaseId:T.releaseId,imageRef:T.imageRef}),h={...T.scope,releaseId:T.releaseId};wG(E,h,R.findings);let r=T.generateImageSbom??CG,N=new AbortController,A=Math.max(100,T.sbomTimeoutMs??120000),S,L=new Promise((U,D)=>{S=setTimeout(()=>{N.abort(),D(Error(`syft-sbom exceeded its ${A}ms timeout`))},A)}),t="unavailable";try{let U=await Promise.race([r(T.imageRef,{signal:N.signal}),L]);sJ(E,h,U),E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"passed",metadata:{imageRef:T.imageRef,format:`cyclonedx-${U.specVersion}+json`,components:U.components.length,localOnly:!0}}),t="image"}catch(U){let D=U instanceof Error?U.message:String(U);try{let C=IG(T.artifactRoot);sJ(E,h,C),E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unsupported",error:`Image inventory was unavailable; attached a package-manifest SBOM instead. ${D}`,metadata:{imageRef:T.imageRef,fallback:"package-manifest",components:C.components.length,localOnly:!0}}),t="manifest"}catch(C){E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unavailable",error:`Image and manifest SBOM generation were unavailable. ${D}; ${C instanceof Error?C.message:String(C)}`,metadata:{imageRef:T.imageRef,localOnly:!0}})}}finally{if(S)clearTimeout(S)}let O=cG({artifactName:T.imageRef,artifact:T.imageSha256?void 0:T.imageRef,artifactSha256:T.imageSha256,invocationId:T.invocationId,startedAt:T.startedAt,completedAt:T.completedAt??new Date().toISOString(),externalParameters:T.externalParameters??{imageRef:T.imageRef}});return XG(E,h,O),{scan:R,sbomSource:t}}async function jl(E){let T=o1();if(T.emptyEnvKey||T.emptyEnvSecret)dE("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.");$(`AWS credentials: ${T.description}`);try{let d=await new sR(E).getCallerIdentity();if(d.Arn)$(`AWS identity: ${d.Arn}`)}catch(_){dE(`Could not verify AWS identity: ${_.message}`)}}function Bl(){try{return uD("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function rF(E,T,_,d){let{ensureManagementDashboard:R}=await x0().then(() => je);R(E,{logger:{info:$,warn:dE}});let h=E.sites||{},r=Object.entries(h);if(r.length===0)return dE("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(d&&!h[d])return Q(`Site '${d}' was not found. Configured sites: ${r.map(([w])=>w).join(", ")}`),!1;let N=r.filter(([w,c])=>{if(!c)return!1;if(d&&w!==d)return!1;if(vT(c)==="bucket")return dE(`Site '${w}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return Qy(c)});if(N.length===0)return!0;if(d)$(`Deploying only '${d}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let A=E.project.slug,L=(E.infrastructure?.compute||{}).runtime||"bun",t=ZT({config:E}),O=Bl(),U=new Map,D={step:(w)=>wE(w),error:(w)=>Q(w)};if(!await k0(E,"beforeDeploy",D))return!1;if(!await k0(E,"beforeBuild",D))return!1;for(let[w,c]of N){let z=vT(c);if(b(`Preparing site: ${w}`),$(`Domain: ${c.domain||"(none)"}`),$(`Source: ${c.root}`),$(`Kind: ${z==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),z==="server-app")$(`Start: ${c.start}`),$(`Port: ${c.port??"(unset)"}`);if(c.build){wE(`Running build: ${c.build}`);try{uD(c.build,{stdio:"inherit",cwd:process.cwd()})}catch(W){return Q(`Build failed for site '${w}': ${W.message}`),!1}}if(!Dd(c.root))return Q(`Build output not found at ${c.root} for site '${w}'`),!1;let j=zl(Jl(),`${A}-${w}-${O}.tar.gz`);wE(`Packaging ${c.root} → ${j}`);try{let W=(c.exclude||[]).map((G)=>`--exclude='${G}'`).join(" ");uD(`tar czf "${j}" -C "${c.root}" ${W} .`,{stdio:"inherit"})}catch(W){return Q(`Failed to package '${w}': ${W.message}`),!1}U.set(w,j)}if(!await k0(E,"afterBuild",D))return!1;let C=await eD({config:d?{...E,sites:Object.fromEntries(N)}:E,rpxConfig:d?E:void 0,environment:T,driver:t,sha:O,runtime:L,tarballForSite:(w)=>{let c=U.get(w);if(!c)throw Error(`Missing tarball for site '${w}'`);return c},logger:{info:(w)=>$(w),warn:(w)=>dE(w),error:(w)=>Q(w),step:(w)=>wE(w),success:(w)=>Z(w)}});if(C&&!await k0(E,"afterDeploy",D))return!1;return C}async function bD(E){let T=new dL;wE("Running pre-deployment security scan...");let _=await T.scan({directory:E.sourceDir,failOnSeverity:E.failOnSeverity||"critical",skipPatterns:E.skipPatterns});return{passed:_.passed,result:_}}function kD(E){let{summary:T,findings:_,scannedFiles:d,duration:R}=E;if($(`
9712
+ `),L=r.index-S,t=R[A-1]||"";if(this.isLikelyPlaceholder(r[0],t))continue;let O=r[1]||r[0];if(h.name==="AWS Secret Key (Generic)"&&/^[a-f0-9]{40}$/i.test(O))continue;if(h.name==="AWS Secret Key (Generic)"&&!this.hasSecretCharacterDiversity(O))continue;if(h.name==="AWS Secret Key (Generic)"&&/^(?:Actions|Commands|Controllers|Handlers|Jobs|Listeners|Middleware|Models|Resources|Services)\//.test(O))continue;if(this.isLowEntropy(O))continue;d.push({file:T,line:A,column:L,match:this.maskSecret(r[0]),pattern:h,context:this.maskSecret(t.trim())})}}return d}isLikelyPlaceholder(E,T){let _=["example","placeholder","your_","YOUR_","xxx","XXX","***","test","TEST","dummy","DUMMY","fake","FAKE","sample","SAMPLE","<your","${","{{","process.env","import.meta.env","CHANGEME","TODO","FIXME"],d=E.toLowerCase(),R=T.toLowerCase();for(let r of _)if(d.includes(r.toLowerCase())||R.includes(r.toLowerCase()))return!0;let h=T.trim();if(h.startsWith("//")||h.startsWith("#")||h.startsWith("*")||h.startsWith("/*")){if(R.includes("example")||R.includes("format:")||R.includes("e.g."))return!0}return!1}isLowEntropy(E){if(E.length<8)return!1;if(new Set(E).size<8)return!0;if(/(.)\1{3,}/.test(E))return!0;return!1}hasSecretCharacterDiversity(E){let T=/[\d+=]/.test(E),_=[/[a-z]/.test(E),/[A-Z]/.test(E),/\d/.test(E),/[/+=]/.test(E)];return T&&_.filter(Boolean).length>=3}maskSecret(E){if(E.length<=8)return"*".repeat(E.length);let T=Math.min(4,Math.floor(E.length*0.2));return E.substring(0,T)+"*".repeat(E.length-T*2)+E.substring(E.length-T)}getFilesToScan(E,T,_){let d=[],R=_||Yn,h=(r)=>{let N=zn(r,{withFileTypes:!0});for(let A of N){let S=Hn(r,A.name);if(A.isDirectory()){if(!T.includes(A.name))h(S)}else if(A.isFile()){let L=Wn(A.name).toLowerCase();if(R.includes(L)||A.name.startsWith(".env")||A.name.endsWith(".config"))d.push(S)}}};return h(E),d}shouldExcludeFile(E){let T=E.split("/").pop()||"";for(let _ of this.excludeFiles)if(_.startsWith("*")){let d=_.substring(1);if(T.endsWith(d))return!0}else if(_.endsWith("*")){let d=_.substring(0,_.length-1);if(T.startsWith(d))return!0}else if(T===_)return!0;return!1}addPattern(E){this.patterns.push(E)}getPatterns(){return[...this.patterns]}}function Qn(E,T){return{status:"unavailable",findings:[],error:`${E.id} exceeded its ${T}ms timeout`,metadata:{timeoutMs:T}}}class AA{posture;defaultTimeoutMs;nowFn;constructor(E,T={}){this.posture=E;this.defaultTimeoutMs=T.defaultTimeoutMs??60000,this.nowFn=T.now??(()=>new Date)}async run(E,T){let _=this.nowFn(),d=Math.max(100,E.timeoutMs??this.defaultTimeoutMs),R=new AbortController,h,r=new Promise((L)=>{h=setTimeout(()=>{R.abort(),L(Qn(E,d))},d)}),N;try{N=await Promise.race([E.scan({...T,signal:R.signal}),r])}catch(L){N={status:"unavailable",findings:[],error:L instanceof Error?L.message:String(L)}}finally{if(h)clearTimeout(h)}let A=this.nowFn(),S={...T,scannerId:E.id,scannerVersion:E.version,status:N.status,findings:N.findings,metadata:N.metadata,error:N.error,startedAt:_.toISOString(),completedAt:A.toISOString(),durationMs:Math.max(0,A.getTime()-_.getTime())};return this.posture.recordScan(S)}async runAll(E,T){return Promise.all(E.map((_)=>this.run(_,T)))}}class n0{scanner;id="source-secrets";version="1.0.0";timeoutMs=30000;constructor(E=new dL){this.scanner=E}async scan(E){if(!E.artifactRoot)return{status:"skipped",findings:[],error:"No artifact root was supplied"};let T=await this.scanner.scan({directory:E.artifactRoot,failOnSeverity:"critical"});return{status:T.passed?"passed":"failed",findings:T.findings.map((_)=>({...E,ruleId:_.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:_.pattern.severity,title:_.pattern.name,description:_.pattern.description,subject:`${_.file}:${_.line}`,evidence:{file:_.file,line:_.line,column:_.column,match:_.match,context:_.context},remediation:"Remove the credential, rotate it at its issuer, and use a managed secret or environment reference."})),metadata:{scannedFiles:T.scannedFiles,summary:T.summary}}}}function Mn(E){let T=E?.toLowerCase();return T==="critical"||T==="high"||T==="medium"||T==="low"?T:"info"}class aJ{id="trivy-image";version;timeoutMs;constructor(E={}){this.version=E.version??"local",this.timeoutMs=E.timeoutMs??120000,this.executable=E.executable??"trivy"}executable;async scan(E){if(!E.imageRef)return{status:"skipped",findings:[],error:"No image reference was supplied"};let T;try{T=Bun.spawn([this.executable,"image","--format","json","--quiet","--scanners","vuln",E.imageRef],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",TRIVY_NO_PROGRESS:"true"}})}catch(A){return{status:"unsupported",findings:[],error:A instanceof Error?A.message:String(A)}}let _=()=>T.kill();E.signal.addEventListener("abort",_,{once:!0});let[d,R,h]=await Promise.all([T.exited,new Response(T.stdout).text(),new Response(T.stderr).text()]);if(E.signal.removeEventListener("abort",_),d!==0)return{status:/not found|enoent/i.test(h)?"unsupported":"unavailable",findings:[],error:h.slice(0,2000)||`Trivy exited with ${d}`};let r=JSON.parse(R),N=[];for(let A of r.Results??[])for(let S of A.Vulnerabilities??[]){let L=S.VulnerabilityID??"unknown-vulnerability";N.push({...E,ruleId:L,severity:Mn(S.Severity),title:S.Title||L,description:S.Description||`${L} affects ${S.PkgName??"an image package"}.`,subject:`${E.imageRef}:${S.PkgName??"unknown"}:${S.InstalledVersion??"unknown"}`,evidence:{image:E.imageRef,target:A.Target??"",cve:L,package:S.PkgName??"",installedVersion:S.InstalledVersion??"",fixedVersion:S.FixedVersion??"",reference:S.PrimaryURL??""},remediation:S.FixedVersion?`Upgrade ${S.PkgName} to ${S.FixedVersion} or later.`:"Remove or replace the affected package and rescan the image."})}return{status:N.length?"failed":"passed",findings:N,metadata:{imageRef:E.imageRef,vulnerabilityCount:N.length,localOnly:!0}}}}import{createHash as Vn,createVerify as h$E}from"node:crypto";import{existsSync as Kn,readFileSync as fn}from"node:fs";import{basename as Pn,join as Zn,resolve as DG}from"node:path";function l0(E){return Vn("sha256").update(E).digest("hex")}function qn(E){let T=[["dependencies","required"],["optionalDependencies","optional"],["devDependencies","excluded"],["peerDependencies","required"]],_=new Map;for(let[d,R]of T){let h=E[d];if(!h||typeof h!=="object"||Array.isArray(h))continue;for(let[r,N]of Object.entries(h)){let A=String(N).replace(/^[~^]/,""),S=`${r}@${A}`;if(!_.has(S))_.set(S,{type:"library",name:r,version:A,purl:`pkg:npm/${encodeURIComponent(r)}@${encodeURIComponent(A)}`,scope:R})}}return[..._.values()].sort((d,R)=>`${d.name}@${d.version}`.localeCompare(`${R.name}@${R.version}`))}function IG(E,T={}){let _=Zn(DG(E),"package.json");if(!Kn(_))throw Error(`Cannot generate an SBOM: ${_} was not found`);let d=fn(_,"utf8"),R=JSON.parse(d),h=String(R.name??Pn(DG(E))),r=String(R.version??"0.0.0"),N=l0(d);return{bomFormat:"CycloneDX",specVersion:"1.5",serialNumber:T.serial??`urn:uuid:${crypto.randomUUID()}`,version:1,metadata:{timestamp:(T.now??new Date).toISOString(),component:{type:"application",name:h,version:r,purl:`pkg:npm/${encodeURIComponent(h)}@${encodeURIComponent(r)}`,hashes:[{alg:"SHA-256",content:N}]},tools:[{vendor:"ts-cloud",name:"security-posture",version:"1.0.0"}]},components:qn(R)}}async function CG(E,T={}){let _=Bun.spawn([T.executable??"syft",E,"-o","cyclonedx-json"],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",SYFT_CHECK_FOR_APP_UPDATE:"false"}}),d=()=>_.kill();T.signal?.addEventListener("abort",d,{once:!0});let[R,h,r]=await Promise.all([_.exited,new Response(_.stdout).text(),new Response(_.stderr).text()]);if(T.signal?.removeEventListener("abort",d),R!==0)throw Error(r.slice(0,2000)||`Syft exited with ${R}`);return JSON.parse(h)}function sJ(E,T,_){let d=JSON.stringify(_);return E.addReleaseArtifact({...T,kind:"sbom",format:`cyclonedx-${_.specVersion}+json`,digest:`sha256:${l0(d)}`,summary:{component:_.metadata.component.name,version:_.metadata.component.version,components:_.components.length},content:d,sensitive:!0})}function wG(E,T,_){let d={total:_.length,critical:0,high:0,medium:0,low:0,info:0,fixable:0};for(let h of _){d[h.severity]++;let r=h.evidence;if(typeof r.fixedVersion==="string"&&r.fixedVersion)d.fixable++}let R=JSON.stringify({releaseId:T.releaseId,generatedAt:new Date().toISOString(),findings:_.map((h)=>({id:h.id,ruleId:h.ruleId,severity:h.severity,subject:h.subject,remediation:h.remediation}))});return E.addReleaseArtifact({...T,kind:"vulnerability_summary",format:"ts-cloud-vulnerability-summary+json",digest:`sha256:${l0(R)}`,summary:d,content:R,sensitive:!0})}function cG(E){if(!E.artifact&&!E.artifactSha256)throw Error("Release provenance requires artifact content or a SHA-256 digest");return{_type:"https://in-toto.io/Statement/v1",subject:[{name:E.artifactName,digest:{sha256:E.artifactSha256?.replace(/^sha256:/,"")??l0(E.artifact)}}],predicateType:"https://slsa.dev/provenance/v1",predicate:{buildDefinition:{buildType:"https://ts-cloud.dev/build/v1",externalParameters:E.externalParameters??{},internalParameters:{},resolvedDependencies:E.resolvedDependencies??[]},runDetails:{builder:{id:"https://ts-cloud.dev/builders/local/v1"},metadata:{invocationId:E.invocationId,startedOn:E.startedAt,finishedOn:E.completedAt}}}}}function XG(E,T,_){let d=JSON.stringify(_);return E.addReleaseArtifact({...T,kind:"provenance",format:"in-toto+slsa-v1+json",digest:`sha256:${l0(d)}`,summary:{subjects:_.subject.length,builder:_.predicate.runDetails.builder.id,buildType:_.predicate.buildDefinition.buildType},content:d,sensitive:!0})}function $d(E,T){let _=E.environments.get(T);if(!_)throw Error(`Security scope for environment '${T}' was not found`);return{organizationId:E.organization.id,projectId:E.project.id,environmentId:_.id}}function i0(E,T){let _=new EN(E.store),d=_.listPolicies(E.organization.id);for(let[R,h]of E.environments){if(d.some((N)=>N.environmentId===h.id))continue;let r=R==="production"||h.kind==="production";d.push(_.createPolicy({organizationId:E.organization.id,environmentId:h.id,name:r?"Production baseline":"Environment baseline",scannerFailMode:r?"closed":"open",requiredScanners:["source-secrets"],rules:r?[{minimumSeverity:"critical",action:"block"},{minimumSeverity:"high",action:"block"},{minimumSeverity:"medium",action:"warn"},{minimumSeverity:"low",action:"record"}]:[{minimumSeverity:"critical",action:"warn"},{minimumSeverity:"high",action:"warn"},{minimumSeverity:"low",action:"record"}],actorId:T}))}return d}function JG(E,T,_,d={}){let R=_.findings.map((h)=>({...T,ruleId:h.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:h.pattern.severity,title:h.pattern.name,description:h.pattern.description,subject:`${h.file}:${h.line}`,evidence:{file:h.file,line:h.line,column:h.column,match:h.match,context:h.context},remediation:"Remove and rotate the credential, then reference it through a managed secret or environment variable."}));return E.recordScan({...T,scannerId:"source-secrets",scannerVersion:d.scannerVersion??"1.0.0",status:d.skipped?"skipped":_.passed?"passed":"failed",findings:d.skipped?[]:R,metadata:{scannedFiles:_.scannedFiles,durationMs:_.duration,summary:_.summary},durationMs:_.duration,error:d.skipped?"The operator explicitly skipped source-secret scanning.":void 0})}function FG(E,T,_="The operator explicitly skipped source-secret scanning."){return E.recordScan({...T,scannerId:"source-secrets",scannerVersion:"1.0.0",status:"skipped",findings:[],error:_})}function xn(E,T){let _=[],d=T.security;if(d?.firewall&&!["active","configured","ok"].includes(String(d.firewall.status)))_.push({...E,ruleId:"host-firewall-disabled",severity:"high",title:"Host firewall is not active",description:String(d.firewall.summary??"The host firewall did not report an active configuration."),subject:"host:firewall",evidence:{status:String(d.firewall.status??"unknown"),rules:Array.isArray(d.firewall.rules)?d.firewall.rules.length:0},remediation:"Apply the declarative firewall policy and confirm only required listeners are public."});for(let R of d?.ports??[]){let h=String(R.listen??""),r=Number(h.match(/:(\d+)$/)?.[1]);if(R.exposure==="public"&&Number.isFinite(r)&&![22,80,443].includes(r))_.push({...E,ruleId:"unexpected-public-listener",severity:"medium",title:`Unexpected public listener on port ${r}`,description:`${String(R.processName??"A process")} is listening publicly outside the standard SSH/HTTP/HTTPS ports.`,subject:`host:port:${r}`,evidence:{protocol:String(R.proto??""),listen:h,process:String(R.processName??"")},remediation:"Bind the service to loopback/private networking or explicitly document and firewall the required public port."})}for(let R of d?.tlsCertificates??[]){let h=Number(R.daysRemaining);if(Number.isFinite(h)&&h<30)_.push({...E,ruleId:"tls-certificate-expiry",severity:h<14?"high":"medium",title:`TLS certificate expires in ${h} days`,description:`${String(R.domain??"A configured domain")} needs renewal.`,subject:`tls:${String(R.domain??"unknown")}`,evidence:{domain:String(R.domain??""),daysRemaining:h,expires:String(R.expires??"")},remediation:"Renew the certificate and verify automatic renewal can complete before expiry."})}for(let R of T.diagnostics??[]){if(R.status==="pass"||R.status==="ok")continue;_.push({...E,ruleId:`diagnostic-${String(R.name??"unknown").toLowerCase().replace(/[^a-z0-9]+/g,"-")}`,severity:R.status==="fail"?"high":"medium",title:String(R.name??"Host security check"),description:String(R.detail??"The host security diagnostic did not pass."),subject:`diagnostic:${String(R.name??"unknown")}`,evidence:{status:String(R.status??"unknown")},remediation:"Follow the diagnostic guidance, rerun the check, and confirm the finding resolves."})}return _}function ZD(E,T,_){let d=!!_.security||Array.isArray(_.diagnostics),R=d?xn(T,_):[];return E.recordScan({...T,scannerId:"host-posture",scannerVersion:"1.0.0",status:!d?"unavailable":R.length?"failed":"passed",findings:R,metadata:{source:"dashboard-live-probe",checks:Array.isArray(_.diagnostics)?_.diagnostics.length:0},error:d?void 0:"Live host posture data was unavailable; source and provider checks remain usable."})}function SA(E,T){let _=E.evaluateGate({...T.scope,operationId:T.operationId}),d=E.listFindings({...T.scope,limit:1000}).filter((R)=>R.status!=="resolved");return{decision:_,summary:{desiredConfigHash:T.desiredConfigHash??null,securityImpact:{critical:d.filter((R)=>R.severity==="critical").length,high:d.filter((R)=>R.severity==="high").length,waived:d.filter((R)=>R.status==="waived").length,assigned:d.filter((R)=>!!R.ownerActorId).length},blockingFindingIds:_.findingIds,policy:{id:_.policyId,version:_.policyVersion},scannerVersions:_.scannerVersions}}}async function zG(E,T){let _=T.scanner??new aJ({timeoutMs:T.scannerTimeoutMs}),R=await new AA(E,{defaultTimeoutMs:T.scannerTimeoutMs??120000}).run(_,{...T.scope,releaseId:T.releaseId,imageRef:T.imageRef}),h={...T.scope,releaseId:T.releaseId};wG(E,h,R.findings);let r=T.generateImageSbom??CG,N=new AbortController,A=Math.max(100,T.sbomTimeoutMs??120000),S,L=new Promise((U,D)=>{S=setTimeout(()=>{N.abort(),D(Error(`syft-sbom exceeded its ${A}ms timeout`))},A)}),t="unavailable";try{let U=await Promise.race([r(T.imageRef,{signal:N.signal}),L]);sJ(E,h,U),E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"passed",metadata:{imageRef:T.imageRef,format:`cyclonedx-${U.specVersion}+json`,components:U.components.length,localOnly:!0}}),t="image"}catch(U){let D=U instanceof Error?U.message:String(U);try{let C=IG(T.artifactRoot);sJ(E,h,C),E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unsupported",error:`Image inventory was unavailable; attached a package-manifest SBOM instead. ${D}`,metadata:{imageRef:T.imageRef,fallback:"package-manifest",components:C.components.length,localOnly:!0}}),t="manifest"}catch(C){E.recordScan({...T.scope,releaseId:T.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unavailable",error:`Image and manifest SBOM generation were unavailable. ${D}; ${C instanceof Error?C.message:String(C)}`,metadata:{imageRef:T.imageRef,localOnly:!0}})}}finally{if(S)clearTimeout(S)}let O=cG({artifactName:T.imageRef,artifact:T.imageSha256?void 0:T.imageRef,artifactSha256:T.imageSha256,invocationId:T.invocationId,startedAt:T.startedAt,completedAt:T.completedAt??new Date().toISOString(),externalParameters:T.externalParameters??{imageRef:T.imageRef}});return XG(E,h,O),{scan:R,sbomSource:t}}async function jl(E){let T=o1();if(T.emptyEnvKey||T.emptyEnvSecret)dE("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.");$(`AWS credentials: ${T.description}`);try{let d=await new sR(E).getCallerIdentity();if(d.Arn)$(`AWS identity: ${d.Arn}`)}catch(_){dE(`Could not verify AWS identity: ${_.message}`)}}function Bl(){try{return uD("git rev-parse --short HEAD",{stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return Date.now().toString(36)}}async function rF(E,T,_,d){let{ensureManagementDashboard:R}=await x0().then(() => je);R(E,{logger:{info:$,warn:dE}});let h=E.sites||{},r=Object.entries(h);if(r.length===0)return dE("infrastructure.compute is set but no sites are configured — nothing to deploy. Add sites to `cloud.config.ts`."),!0;if(d&&!h[d])return Q(`Site '${d}' was not found. Configured sites: ${r.map(([w])=>w).join(", ")}`),!1;let N=r.filter(([w,c])=>{if(!c)return!1;if(d&&w!==d)return!1;if(vT(c)==="bucket")return dE(`Site '${w}' targets a bucket — skipping compute deploy (handled by the static-site path).`),!1;return Qy(c)});if(N.length===0)return!0;if(d)$(`Deploying only '${d}'. Other sites keep their current release; proxy routes are still regenerated in full.`);let A=E.project.slug,L=(E.infrastructure?.compute||{}).runtime||"bun",t=ZT({config:E}),O=Bl(),U=new Map,D={step:(w)=>wE(w),error:(w)=>Q(w)};if(!await k0(E,"beforeDeploy",D))return!1;if(!await k0(E,"beforeBuild",D))return!1;for(let[w,c]of N){let z=vT(c);if(b(`Preparing site: ${w}`),$(`Domain: ${c.domain||"(none)"}`),$(`Source: ${c.root}`),$(`Kind: ${z==="server-static"?"static (shipped to /var/www)":"app (systemd service)"}`),z==="server-app")$(`Start: ${c.start}`),$(`Port: ${c.port??"(unset)"}`);if(c.build){wE(`Running build: ${c.build}`);try{uD(c.build,{stdio:"inherit",cwd:process.cwd()})}catch(W){return Q(`Build failed for site '${w}': ${W.message}`),!1}}if(!Dd(c.root))return Q(`Build output not found at ${c.root} for site '${w}'`),!1;let j=zl(Jl(),`${A}-${w}-${O}.tar.gz`);wE(`Packaging ${c.root} → ${j}`);try{let W=(c.exclude||[]).map((G)=>`--exclude='${G}'`).join(" ");uD(`tar czf "${j}" -C "${c.root}" ${W} .`,{stdio:"inherit"})}catch(W){return Q(`Failed to package '${w}': ${W.message}`),!1}U.set(w,j)}if(!await k0(E,"afterBuild",D))return!1;let C=await eD({config:d?{...E,sites:Object.fromEntries(N)}:E,rpxConfig:d?E:void 0,environment:T,driver:t,sha:O,runtime:L,tarballForSite:(w)=>{let c=U.get(w);if(!c)throw Error(`Missing tarball for site '${w}'`);return c},logger:{info:(w)=>$(w),warn:(w)=>dE(w),error:(w)=>Q(w),step:(w)=>wE(w),success:(w)=>Z(w)}});if(C&&!await k0(E,"afterDeploy",D))return!1;return C}async function bD(E){let T=new dL;wE("Running pre-deployment security scan...");let _=await T.scan({directory:E.sourceDir,failOnSeverity:E.failOnSeverity||"critical",skipPatterns:E.skipPatterns});return{passed:_.passed,result:_}}function kD(E){let{summary:T,findings:_,scannedFiles:d,duration:R}=E;if($(`
9713
9713
  Scanned ${d} files in ${R}ms`),T.critical>0)Q(` Critical: ${T.critical}`);else $(` Critical: ${T.critical}`);if(T.high>0)dE(` High: ${T.high}`);else $(` High: ${T.high}`);if($(` Medium: ${T.medium}`),$(` Low: ${T.low}`),_.length>0){$(`
9714
9714
  Findings:`);let h=_.filter((L)=>L.pattern.severity==="critical"),r=_.filter((L)=>L.pattern.severity==="high"),N=_.filter((L)=>L.pattern.severity==="medium"),A=_.filter((L)=>L.pattern.severity==="low"),S=(L,t,O)=>{if(L.length>0){console.log(`
9715
9715
  ${Ur(`[${t}]`,O)}`);for(let U of L.slice(0,10))$(` ${U.pattern.name}`),$(` File: ${U.file}:${U.line}`),$(` Match: ${U.match}`);if(L.length>10)$(` ... and ${L.length-10} more ${t.toLowerCase()} findings`)}};S(h,"CRITICAL","red"),S(r,"HIGH","yellow"),S(N,"MEDIUM","blue"),S(A,"LOW","gray")}}function E9(E,T){let _=Object.keys(E.environments??{});if(T&&_.includes(T))return T;if(_.includes("production"))return"production";if(_[0])return _[0];throw Error("A configured environment is required for security policy evaluation")}function NF(E,T,_){let d=E9(E,T),R=lE(process.cwd(),E);try{let h=new EN(R.store);i0(R);let r=$d(R,d);if(_)JG(h,r,_);else FG(h,r);let N=SA(h,{scope:r,desiredConfigHash:R.project.desiredConfigHash});return $(`Security policy: ${N.decision.policyId} v${N.decision.policyVersion} — ${N.decision.outcome.toUpperCase()}`),$(`Security decision: ${N.decision.explanation}`),{allowed:N.decision.outcome!=="block",explanation:N.decision.explanation}}finally{R.store.close()}}async function Wl(E,T){let _=E9(E),d=lE(process.cwd(),E);try{let R=new EN(d.store);i0(d);let h=$d(d,_),r=T.imageSha256?`${T.imageRef}@sha256:${T.imageSha256.replace(/^sha256:/,"")}`:T.imageRef;wE("Scanning the built image and producing release security artifacts...");let N=await zG(R,{scope:h,releaseId:r,imageRef:T.imageRef,imageSha256:T.imageSha256,artifactRoot:T.artifactRoot,invocationId:T.invocationId,startedAt:T.startedAt,externalParameters:{imageRef:T.imageRef,artifactRoot:T.artifactRoot}});$(`Image scanner: ${N.scan.run.status} (${N.scan.findings.length} findings)`),$(`Release SBOM: ${N.sbomSource==="image"?"full image inventory":N.sbomSource==="manifest"?"package-manifest fallback":"unavailable"}`);let A=SA(R,{scope:h,operationId:T.invocationId,desiredConfigHash:d.project.desiredConfigHash});return $(`Release policy: ${A.decision.policyId} v${A.decision.policyVersion} — ${A.decision.outcome.toUpperCase()}`),$(`Release decision: ${A.decision.explanation}`),{allowed:A.decision.outcome!=="block",explanation:A.decision.explanation}}finally{d.store.close()}}function SF(E){E.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)=>{b("Pre-Deployment Security Scan");try{let _=T?.source||".",d=T?.failOn||"critical",R=T?.skipPatterns?.split(",").map((N)=>N.trim())||[];if(!Dd(_)){Q(`Source directory not found: ${_}`);return}$(`Source: ${_}`),$(`Fail on: ${d} or higher severity`);let{passed:h,result:r}=await bD({sourceDir:_,failOnSeverity:d,skipPatterns:R});if(kD(r),h)Z(`