UNPKG

phala

Version:
62 lines (61 loc) 72.6 kB
#!/usr/bin/env node import{$ as Ke,L as ue,M as xe,N as Q,O as L,P as Fe,R as Me,S as Te,T as Ve,U as Ue,V as Ne,W as Re,Y as ee,Z as Le,_ as Oe,a as e,aa as ze,b as le,ba as O,c as R,d as B,e as pe,f as P,g as y,h as M,i as T,j as V,k as de,l as Ie,m as Pe,n as Ae}from"./chunk-UU6UDBBR.js";import{Command as Co}from"commander";import Be from"chalk";var Ge=Be.hex("#cdfa50"),je=Ge(` \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FF\u2847\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u281E\u281B\u2809\u2819\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u281B\u28B6\u28C4\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u28FF\u28E6\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28FF\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u28FF\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2838\u28FF\u28F7\u28C4\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28F4\u28FF\u28FF\u287F\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28BF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2800\u2800\u28C0\u28F4\u28F6\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2801\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283B\u283F\u283F\u283F\u283F\u2803\u2800\u2880\u28FE\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u281B\u280B\u2801\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28FF\u287F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28C0\u2864\u2824\u2824\u2834\u2812\u2812\u2812\u2812\u2812\u28BF\u287F\u2813\u2812\u2812\u2822\u2824\u2824\u2824\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28EF\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E8\u28FF\u28E6\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28BB\u28FF\u28FF\u28FF\u28FF\u28FF\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u284F\u2809\u281B\u28FF\u28C6\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u28C0\u28C0\u28C0\u28C0\u2878\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u2800\u28F8\u287F\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2839\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u2847\u2800\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2803\u2880\u28E0\u28F4\u287F\u2803\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u2887\u28C0\u28C0\u28C0\u28C0\u28F8\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u283F\u283F\u281B\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2860\u2800\u2800\u2800\u2800\u2808\u283B\u28BF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u280B\u2800\u2800\u2800\u2800\u2820\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 `),_o=Ge(` \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FF\u2847\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u281E\u281B\u2809\u2819\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u281B\u28B6\u28C4\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u28FF\u28E6\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28FF\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u28FF\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2838\u28FF\u28F7\u28C4\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28F4\u28FF\u28FF\u287F\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28BF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2800\u2800\u28C0\u28F4\u28F6\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2801\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283B\u283F\u283F\u283F\u283F\u2803\u2800\u2880\u28FE\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u281B\u280B\u2801\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28FF\u287F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28C0\u2864\u2824\u2824\u2834\u2812\u2812\u2812\u2812\u2812\u28BF\u287F\u2813\u2812\u2812\u2822\u2824\u2824\u2824\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28EF\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E8\u28FF\u28E6\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28BB\u28FF\u28FF\u28FF\u28FF\u28FF\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u284F\u2809\u281B\u28FF\u28C6\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u28C0\u28C0\u28C0\u28C0\u2878\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u2800\u28F8\u287F\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2839\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u2847\u2800\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2803\u2880\u28E0\u28F4\u287F\u2803\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u2887\u28C0\u28C0\u28C0\u28C0\u28F8\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u283F\u283F\u281B\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2860\u2800\u2800\u2800\u2800\u2808\u283B\u28BF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u280B\u2800\u2800\u2800\u2800\u2820\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800 \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800 `),So=Be.cyan("PHALA TEE CLOUD CLI");import{Command as et}from"commander";import{Command as Yr}from"commander";import Wr from"prompts";var He=new Yr().name("login").description("Set the API key for authentication").argument("[api-key]","Phala Cloud API key to set").action(async o=>{try{let r;if(!o)o=(await Wr({type:"password",name:"apiKey",message:"Enter your API key:",validate:async i=>{if(i.length===0)return"API key cannot be empty";try{if(await le(i),r=await ue(),!r.username)throw await B(),new Error("Invalid API key")}catch{throw new Error("Invalid API key")}return!0}})).apiKey;else if(await le(o),r=await ue(o),!r.username)throw await B(),new Error("Invalid API key");e.success(`Welcome ${r.username}! API key validated and saved successfully`),e.break(),e.info(`Open in Web UI at ${y}/dashboard/`)}catch(r){e.error(`Failed to set API key: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Jr}from"commander";var qe=new Jr().name("logout").description("Remove the stored API key").action(async()=>{try{await B(),e.success("API key removed successfully")}catch(o){e.error(`Failed to remove API key: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{createClient as Zr}from"@phala/cloud";import{Command as Xr}from"commander";import{safeGetCurrentUser as Qr}from"@phala/cloud";var Ye=new Xr().name("status").description("Check authentication status").option("-j, --json","Output in JSON format").option("-d, --debug","Enable debug output").action(async o=>{try{let r=o.debug||process.env.DEBUG?.toLowerCase()==="true",t=R();if(!t){console.log('Not authenticated. Please set an API key with "phala auth login"');return}r&&e.debug(`Using API key: ${t.substring(0,5)}...`);try{let i=Zr({apiKey:t}),n=await Qr(i);if(!n.success){e.error("Failed to get user information"),n.error&&e.error(`Error: ${n.error.message}`);return}let a=n.data,s=process.env.PHALA_CLOUD_API_PREFIX||"https://cloud-api.phala.network/api/v1";if(o.json){console.log(JSON.stringify({apiUrl:s,username:a.username,team_name:a.team_name},null,2));return}console.log(`Integrated API: ${s}`),console.log(`Logged in as: ${a.username}`),console.log(`Current Workspace: ${a.team_name}`)}catch(i){console.error("Authentication failed. Your API key may be invalid or expired."),console.log('Please set a new API key with "phala auth login"'),r&&e.debug(`Error details: ${i instanceof Error?i.message:String(i)}`)}}catch(r){e.error(`Failed to check authentication status: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var We=new et().name("auth").description("Authenticate with Phala Cloud").addCommand(He).addCommand(qe).addCommand(Ye);import{Command as yt}from"commander";import{Command as pt}from"commander";import{execa as nt}from"execa";import x from"node:fs";import H from"node:path";import st from"handlebars";import{exec as at,spawn as ct}from"node:child_process";import{promisify as mt}from"node:util";import er from"node:os";import rt from"inquirer";import fe from"node:fs";import ge from"node:path";function U(o,r=process.cwd()){let t=ge.resolve(r,o);if(!fe.existsSync(t))throw new Error(`File not found at ${t}`);return!0}async function $(o,r,t="file",i=process.cwd()){return(await rt.prompt([{type:"input",name:t,message:o,default:r,validate:a=>{let s=ge.resolve(i,a);return fe.existsSync(s)?!0:`File not found at ${s}`}}]))[t]}function K(o,r){for(let t of o){let i=ge.join(process.cwd(),t);if(fe.existsSync(i))return r?e.info(r.replace("{path}",i)):e.info(`File detected: ${i}`),t}}import*as h from"node:fs";import*as S from"node:path";import*as D from"node:os";import{execSync as A,spawn as tt}from"node:child_process";import*as he from"node:net";var C={version:"0.5.3",baseUrl:"https://github.com/Dstack-TEE/dstack/releases/download/v0.5.3",installDir:S.join(D.homedir(),".phala-cloud","simulator"),defaultLogPath:S.join(D.homedir(),".phala-cloud","logs","dstack-simulator.log"),platforms:{darwin:{filename:"dstack-simulator-0.5.3-aarch64-apple-darwin.tgz",extractedFolder:"0.5.3",socketPath:S.join(D.homedir(),".phala-cloud","simulator","0.5.3","dstack.sock")},linux:{filename:"dstack-simulator-0.5.3-x86_64-linux-musl.tgz",extractedFolder:"0.5.3",socketPath:S.join(D.homedir(),".phala-cloud","simulator","0.5.3","dstack.sock")},win32:{filename:"dstack-simulator-0.5.3-x86_64-pc-windows-msvc.tgz",extractedFolder:"dstack-simulator-0.5.3-x86_64-pc-windows-msvc",socketPath:"127.0.0.1:8090"}}};function Je(){try{if(!h.existsSync(C.installDir))return!1;let o=D.platform();if(!C.platforms[o])throw new Error(`Unsupported platform: ${o}`);let r=S.join(C.installDir,C.platforms[o].extractedFolder);if(!h.existsSync(r))return!1;let i=S.join(r,o==="win32"?"dstack-simulator.exe":"dstack-simulator");return h.existsSync(i)}catch(o){return e.error("Error checking if simulator is installed:",o),!1}}function G(){let o=D.platform();if(!C.platforms[o])throw new Error(`Unsupported platform: ${o}. Only darwin, linux, and win32 are supported.`);return o}async function Ze(o){let r=t=>{e.info(t),o&&o(t)};try{let t=G(),i=C.platforms[t];if(t==="win32"){try{A("tar --version",{stdio:"ignore"})}catch{throw new Error("Windows 10 build 17063 or later is required (includes tar command). Please update your Windows version.")}throw new Error("Windows platform is currently not supported. Support will be added in a future release.")}h.existsSync(C.installDir)||(e.info(`Creating installation directory at ${C.installDir}`),h.mkdirSync(C.installDir,{recursive:!0})),process.chdir(C.installDir);let n=`${C.baseUrl}/${i.filename}`;e.info(`Downloading simulator from ${n}`),A(`wget ${n}`,{stdio:"inherit"});let a=S.join(C.installDir,i.extractedFolder);h.existsSync(a)||h.mkdirSync(a,{recursive:!0}),e.info(`Extracting ${i.filename} to ${a}`);let s=`tar -xvf "${i.filename}" -C "${a}" --strip-components=1`;e.debug(`Running: ${s}`);try{A(s,{stdio:"inherit"}),h.unlinkSync(i.filename)}catch(c){throw e.error(`Failed to extract ${i.filename}:`,c),new Error("Failed to extract simulator archive. Make sure you have sufficient permissions and disk space.")}e.success("Simulator installation completed successfully")}catch(t){throw e.error("Error installing simulator:",t),new Error(`Failed to install simulator: ${t}`)}}var ye=()=>S.join(D.tmpdir(),"dstack-simulator.pid");function ot(o){return Buffer.byteLength(o,"utf8")>104}function re(){try{let o=ye();if(h.existsSync(o)){let r=parseInt(h.readFileSync(o,"utf-8").trim(),10);try{return process.kill(r,0),r}catch{h.unlinkSync(o)}}return null}catch(o){return e.warn("Error checking simulator PID:",o),null}}function it(o,r){try{let t=ye();r&&e.info(`Saving simulator PID ${o} to: ${t}`),h.writeFileSync(t,o.toString(),"utf-8")}catch(t){e.warn("Failed to save simulator PID:",t)}}async function Xe(o={}){try{let r=G(),t=C.platforms[r],i=S.join(C.installDir,t.extractedFolder),n=re();if(n)throw new Error(`Simulator is already running with PID: ${n}`);if(r!=="win32"&&ot(t.socketPath))throw new Error(`Socket path is too long (${t.socketPath.length} chars, max 104): ${t.socketPath}`);if(r!=="win32"&&h.existsSync(t.socketPath)){e.warn(`Removing existing socket file: ${t.socketPath}`);try{h.unlinkSync(t.socketPath)}catch(m){e.warn(`Failed to remove existing socket file: ${m}`)}}process.chdir(i);let a=r==="win32"?"dstack-simulator.exe":"./dstack-simulator";o.verbose&&r!=="win32"&&e.info(`Using socket path: ${t.socketPath}`);let s={background:o.background??!0,logToFile:o.logToFile??!0,logFilePath:o.logFilePath??C.defaultLogPath};if(s.logToFile){let m=S.dirname(s.logFilePath);h.existsSync(m)||h.mkdirSync(m,{recursive:!0}),o.verbose&&e.info(`Simulator logs will be written to: ${s.logFilePath}`)}o.verbose&&e.info(`Starting simulator with: ${a}`);let c=s.logToFile?["ignore",h.openSync(s.logFilePath,"a"),h.openSync(s.logFilePath,"a")]:"inherit",l=tt(a,[],{stdio:c,shell:r==="win32",detached:s.background});if(s.logToFile&&Array.isArray(c)&&(typeof c[1]=="number"&&h.closeSync(c[1]),typeof c[2]=="number"&&h.closeSync(c[2])),s.logToFile){let d=` === Simulator started at ${new Date().toISOString()} === Command: ${a} `;h.appendFileSync(s.logFilePath,d)}return l.pid&&it(l.pid,o.verbose),s.background&&(l.unref(),o.verbose&&e.success("Simulator is running in the background")),await ve(),l}catch(r){throw e.error("Error running simulator:",r),new Error(`Failed to run simulator: ${r}`)}}async function j(){try{let o=G(),r=C.platforms[o];if(o==="darwin"||o==="linux"){let t=r.socketPath;return h.existsSync(t)?new Promise(i=>{let n=he.createConnection({path:t}).on("connect",()=>{n.end(),i(!0)}).on("error",()=>{i(!1)});setTimeout(()=>{n.end(),i(!1)},1e3)}):!1}if(o==="win32"){let t="127.0.0.1";return new Promise(n=>{let a=he.createConnection({host:t,port:8090}).on("connect",()=>{a.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{a.end(),n(!1)},1e3)})}return!1}catch(o){return e.error("Error checking if simulator is running:",o),!1}}async function Qe(){try{let o=re();if(!await j()&&!o)return e.info("Simulator is not running"),!0;let t=G(),i=!1;if(t==="win32")try{o?(e.info(`Stopping simulator process (PID: ${o})...`),process.kill(o,"SIGTERM")):A("taskkill /F /IM dstack-simulator.exe",{stdio:"ignore"}),i=!0}catch(a){if(a.code!=="ESRCH")return e.error("Failed to stop simulator:",a),!1;i=!0}else try{o?(e.info(`Stopping simulator process (PID: ${o})...`),process.kill(o,"SIGTERM")):A("pkill -f dstack-simulator",{stdio:"ignore"}),i=!0}catch(a){if(a.code!=="ESRCH")return e.error("Failed to stop simulator:",a),!1;i=!0}let n=ye();if(h.existsSync(n))try{h.unlinkSync(n)}catch(a){e.warn("Failed to remove PID file:",a)}return await N(),i&&e.success("Simulator stopped successfully"),i}catch(o){return e.error("Error stopping simulator:",o),!1}}function te(){let o=G(),r=C.platforms[o];return o==="win32"?"http://127.0.0.1:8090":`${r.socketPath||"/tmp/dstack.sock"}`}async function ve(o){try{let r=te(),t=o||r;await A(`export DSTACK_SIMULATOR_ENDPOINT=${t}`);let i=t.replace(/dstack\.sock$/,"tappd.sock");return await A(`export TAPPD_SIMULATOR_ENDPOINT=${i}`),e.success("Setting environment for current process..."),e.success(` DSTACK_SIMULATOR_ENDPOINT=${t}`),e.success(` TAPPD_SIMULATOR_ENDPOINT=${i}`),t}catch(r){throw e.error("Error setting simulator endpoint environment variable:",r),new Error(`Failed to set simulator endpoint: ${r}`)}}async function N(){try{return await A("unset DSTACK_SIMULATOR_ENDPOINT"),await A("unset TAPPD_SIMULATOR_ENDPOINT"),e.debug("Deleted simulator endpoint environment variables from current process"),!0}catch(o){return e.warn("Error while unsetting simulator endpoint environment variables:",o),!1}}var q=mt(at),rr=".phala-cloud/logs",lt=".phala-cloud/compose",tr=10,b=class{username;image;registry;constructor(r,t,i){this.image=r,this.username=t||"",this.registry=i||""}ensureLogsDir(){let r=H.resolve(rr);x.existsSync(r)||x.mkdirSync(r,{recursive:!0})}getLogFilePath(r,t){let i=new Date().toISOString().replace(/[:.]/g,"-");return H.resolve(rr,`${t||this.image}-${r}-${i}.log`)}getSystemArchitecture(){let r=er.arch();switch(r){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return r}}spawnProcess(r,t,i,n){return new Promise((a,s)=>{let c=ct(r,t);this.ensureLogsDir();let l=this.getLogFilePath(i,n),m=x.createWriteStream(l,{flags:"a"}),d=[],g=(p,u=!1)=>{let v=p.toString().split(` `);m.write(p);for(let f of v)if(f.trim()){d.push(f),d.length>tr&&d.shift(),console.clear(),console.log(`Latest ${tr} lines (full log at ${l}):`),console.log("-".repeat(50));for(let I of d)u?console.error(I):console.log(I)}};c.stdout.on("data",p=>g(p)),c.stderr.on("data",p=>g(p,!0)),c.on("close",p=>{m.end(),p===0?(console.log(` Operation completed. Full log available at: ${l}`),a()):s(new Error(`Process exited with code ${p}. Check log file: ${l}`))}),c.on("error",p=>{m.end(),s(p)})})}setCredentials(r,t){this.username=r,t&&(this.registry=t)}async buildImage(r,t){try{let i=this.getSystemArchitecture(),n=`${this.username}/${this.image}:${t}`,a=e.startSpinner(`Building Docker image ${this.username}/${this.image}:${t}`);U(r);let s=["build","-t",n,"-f",r];return i==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),s.push("--platform","linux/amd64")),s.push("."),await this.spawnProcess("docker",s,"build",this.image),a.stop(!0,`Docker image ${n} built successfully`),!0}catch(i){return e.error(`Failed to build Docker image: ${i instanceof Error?i.message:String(i)}`),!1}}async pushImage(r){try{let t=e.startSpinner(`Pushing Docker image ${r} to Docker Hub`);if(!await P())throw t.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let n=r;return console.log(`Pushing image ${n} to Docker Hub...`),await this.spawnProcess("docker",["push",n],"push",r.replace(/.*\/+([\w-]+):.*$/g,"$1")),t.stop(!0,`Docker image ${n} pushed successfully`),!0}catch(t){return e.error(`Failed to push Docker image: ${t instanceof Error?t.message:String(t)}`),!1}}async login(r,t,i){try{let n=e.startSpinner(`Logging in to Docker Hub as ${r}`);if(await this.checkLogin())return n.stop(!0,"Already logged in to Docker Hub"),this.setCredentials(r,i),!0;if(!t)throw n.stop(!1),new Error("Password is required for Docker login");try{await nt("docker",["login",...i?[i]:[],"-u",r,"--password-stdin"],{input:t,timeout:1e4})}catch(s){throw s.timedOut?(n.stop(!1),new Error("Docker login timed out. Please check your credentials and try again.")):s}return n.stop(!0,"Logged in to Docker Hub successfully"),this.setCredentials(r,i),!0}catch(n){return e.error(`Failed to login to Docker Hub: ${n instanceof Error?n.message:String(n)}`),!1}}async checkLogin(){try{let r=er.homedir(),t=H.join(r,".docker","config.json");if(!x.existsSync(t))return!1;let i=JSON.parse(x.readFileSync(t,"utf-8"));return!!(i?.auths&&Object.keys(i.auths).length>0)}catch(r){return e.debug(`Docker login check failed: ${r instanceof Error?r.message:String(r)}`),!1}}async buildComposeFile(r,t,i){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let n=i==="eliza"?Ie:Pe,a=Ae.parse({template:n}),s=H.resolve(lt);x.existsSync(s)||(e.info(`Creating directory: ${s}`),x.mkdirSync(s,{recursive:!0}));let c=[];t&&(c=x.readFileSync(t,"utf-8").split(` `).filter(u=>u&&!u.startsWith("#")).map(u=>{let v=u.indexOf("#");return v>0&&(u=u.substring(0,v).trim()),u.trim()}).filter(u=>u.includes("=")).map(u=>{let[v,f]=u.split("=",2),I=v.trim();return(f?f.trim():"")===""?null:`${I}=${I}`}).filter(Boolean));let l=r,d=st.compile(a.template,{noEscape:!0})({imageName:l,envVars:c.map(p=>p.replace(/=.*/,`=\${${p.split("=")[0]}}`))}),g=H.join(s,`${r.replace(/.*\/+([\w-]+):.*$/g,"$1")}-tee-compose.yaml`);return x.writeFileSync(g,d),e.success(`Backup of docker compose file created at: ${g}`),g}async runComposeLocally(r,t){try{let i=e.startSpinner(`Running Docker Compose file at ${r}`);U(r);let n=["-f",r,"up","-d"];return t&&(U(t),n.splice(2,0,"--env-file",t)),await q(`docker compose ${n.join(" ")}`),i.stop(!0,"Docker Compose file running successfully"),!0}catch(i){return e.error(`Failed to run Docker Compose file: ${i instanceof Error?i.message:String(i)}`),!1}}async runSimulator(r,t){try{e.info(`Running TEE simulator with image ${r}`),e.info("Pulling latest simulator image..."),await q(`docker pull ${r}`),e.info("Starting simulator in background...");let{stdout:i}=await q(`docker run -d --name tee-simulator --rm -p ${t}:${t} ${r}`),n=i.trim();return e.success(`TEE simulator running successfully. Container ID: ${n}`),e.break(),e.break(),e.info("Useful commands:"),e.info(`- View logs: docker logs -f ${n}`),e.info(`- Stop simulator: docker stop ${n}`),ve(`http://localhost:${t}`),!0}catch(i){return e.error(`Failed to run TEE simulator: ${i instanceof Error?i.message:String(i)}`),!1}}async stopSimulator(){try{let r=e.startSpinner("Stopping TEE simulator...");return await q("docker stop tee-simulator"),await N(),r.stop(!0,"TEE simulator stopped successfully"),!0}catch(r){return e.error(`Failed to stop TEE simulator: ${r instanceof Error?r.message:String(r)}`),!1}}static async listLocalImages(){try{let{stdout:r}=await q('docker images --format "{{.Repository}}:{{.Tag}}"'),i=(await P())?.username;return r.split(` `).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${i}/`)).map(a=>({imageName:a}))}catch(r){return e.error(`Failed to list local Docker images: ${r instanceof Error?r.message:String(r)}`),[]}}};import or from"prompts";var ir=new pt().name("login").description("Login to Docker Hub").option("-u, --username <username>","Docker Hub username").option("-p, --password <password>","Docker Hub password").option("-r, --registry <registry>","Docker registry URL").action(async o=>{try{let r=o.username,t=o.password,i=o.registry;if(!r){e.info("First we need your Docker Hub username to check if you are already logged in.");let c=await or({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:l=>l.length>0?!0:"Username cannot be empty"});c.username||(e.error("Username is required"),process.exit(1)),r=c.username}let n=new b("",r,i);if(await n.login(r)){e.success(`${r} is logged in to Docker Hub`),await pe({username:r,registry:i||null});return}if(!t){let c=await or({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:l=>l.length>0?!0:"Password cannot be empty"});c.password||(e.error("Password is required"),process.exit(1)),t=c.password}await n.login(r,t,i)||(e.error("Failed to login to Docker Hub"),process.exit(1)),await pe({username:r,registry:i||null}),e.success("Logged in to Docker Hub successfully")}catch(r){e.error(`Failed to login to Docker Hub: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as dt}from"commander";import nr from"node:path";import sr from"inquirer";import ut from"node:fs";var ar=new dt().name("build").description("Build a Docker image").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").option("-f, --file <file>","Path to Dockerfile","Dockerfile").action(async o=>{try{let r=await P();if(r||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!o.image){let s=await sr.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:c=>c.trim()?!0:"Image name is required"}]);o.image=s.image}if(!o.tag){let s=await sr.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:c=>c.trim()?!0:"Tag is required"}]);o.tag=s.tag}let t=nr.resolve(process.cwd(),o.file);ut.existsSync(t)||(e.info(`Default Dockerfile not found at ${t}`),o.file=await $("Enter the path to your Dockerfile:","Dockerfile","file"));let i=nr.resolve(process.cwd(),o.file);await new b(o.image,r.username,r.registry).buildImage(i,o.tag)||(e.error("Failed to build Docker image"),process.exit(1)),e.success(`Docker image ${r.username}/${o.image}:${o.tag} built successfully`)}catch(r){e.error(`Failed to build Docker image: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as ft}from"commander";import gt from"inquirer";var cr=new ft().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Full image name (e.g. username/image:tag)").action(async o=>{try{let r=await P();r||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let t=o.image;if(!t){let a=await b.listLocalImages();if(a.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!t){let s=Array.from(new Set(a.map(l=>l.imageName))),{selectedImage:c}=await gt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:s}]);t=c}}await new b("",r.username,r.registry).pushImage(t)||(e.error("Failed to push Docker image"),process.exit(1)),e.success(`Docker image ${t} pushed successfully`)}catch(r){e.error(`Failed to push Docker image: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as ht}from"commander";import Y from"inquirer";import W from"node:fs";import oe from"node:path";var mr=new ht().name("generate").description("Generate a Docker Compose file").option("-i, --image <imageName>","Docker image name to use in the compose file (e.g. phala/phala-cloud)").option("-e, --env-file <envFile>","Path to environment variables file").option("-o, --output <output>","Output path for generated docker-compose.yml").option("--template <template>","Template to use for the generated docker-compose.yml").action(async o=>{try{let r=await P();(!r||!r.username)&&(e.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let t=o.image;if(!t){let c=await b.listLocalImages();if(c.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!t){let l=Array.from(new Set(c.map(d=>d.imageName))),{selectedImage:m}=await Y.prompt([{type:"list",name:"selectedImage",message:"Select an image to use in the compose file:",choices:l}]);t=m}}let i=o.envFile;if(i)try{U(i)}catch{e.error(`File not found: ${i}`),process.exit(1)}else{let c=oe.join(process.cwd(),".env");if(W.existsSync(c)){let{useDefault:m}=await Y.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);m&&(i=c)}if(!i){let{envPath:m}=await Y.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:d=>{try{return U(d),!0}catch{return`File not found: ${d}`}}}]);i=m}}let n=o.output;if(!n&&(n=oe.join(process.cwd(),"docker-compose.yml"),W.existsSync(n))){let{confirmOverwrite:c}=await Y.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${n} already exists. Overwrite?`,default:!1}]);if(!c){let{customPath:l}=await Y.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:oe.join(process.cwd(),"docker-generated-compose.yml")}]);n=l}}let a=new b("",r.username,r.registry);i?e.info(`Generating Docker Compose file for ${t} using env file: ${i}`):e.info(`Generating Docker Compose file for ${t} without env file`);let s=await a.buildComposeFile(t,i,o.template);if(s!==n){let c=oe.dirname(n);W.existsSync(c)||(e.info(`Creating directory: ${c}`),W.mkdirSync(c,{recursive:!0})),W.copyFileSync(s,n)}e.success(`Docker Compose file generated successfully: ${n}`)}catch(r){e.error(`Failed to generate Docker Compose file: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var lr=new yt().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(ir).addCommand(ar).addCommand(cr).addCommand(mr);import{Command as wt}from"commander";import{Command as vt}from"commander";var pr=new vt().name("start").description("Start the TEE simulator").option("-p, --port <port>","Simulator port (default: 8090)","8090").option("-v, --verbose","Enable verbose output",!1).action(async o=>{try{if(Je()||await Ze(),await j()){e.success("TEE simulator is already running");return}let t=await Xe({verbose:o.verbose});e.success("TEE simulator started successfully")}catch(r){e.error(`Failed to start TEE simulator: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Ct}from"commander";var dr=new Ct().name("stop").description("Stop the TEE simulator").action(async()=>{try{await Qe()||(e.error("Failed to stop TEE simulator"),process.exit(1)),e.success("TEE simulator stopped successfully")}catch(o){e.error(`Failed to stop TEE simulator: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});var Ce=new wt().name("simulator").description("TEE simulator commands").addCommand(pr).addCommand(dr);Ce.action(async()=>{try{let o=await j(),r=re();if(o&&r){let t=te(),i=te(),n=i.replace(/dstack\.sock$/,"tappd.sock");console.log(`\u2713 TEE simulator is running (PID: ${r})`),console.log(` Set these environment variables to use the simulator:`),console.log(` export DSTACK_SIMULATOR_ENDPOINT=${i}`),console.log(` export TAPPD_SIMULATOR_ENDPOINT=${n}`)}else console.log("TEE simulator is not running"),console.log(` To start the simulator, run:`),console.log(" phala simulator start")}catch(o){console.error("Error checking simulator status:",o)}});import{Command as Ot}from"commander";import{Command as kt}from"commander";import we from"chalk";var ur=new kt().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async o=>{try{let r=e.startSpinner("Fetching CVMs"),t=await xe();if(r.stop(!0),!t||t.length===0){e.info("No CVMs found");return}if(o.json){console.log(JSON.stringify(t,null,2));return}for(let i of t)e.keyValueTable({Name:i.name,"App ID":`app_${i.hosted.app_id}`,"CVM ID":i.hosted.id.replace(/-/g,""),Region:i.node.region_identifier,Status:i.status==="running"?we.green(i.status):i.status==="stopped"?we.red(i.status):we.yellow(i.status),"Node Info URL":i.hosted.app_url,"App URL":`${y}/dashboard/cvms/${i.hosted.id.replace(/-/g,"")}`}),e.break();e.success(`Found ${t.length} CVMs`),e.break(),e.info(`Go to ${y}/dashboard/ to view your CVMs`)}catch(r){e.error(`Failed to list CVMs: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as _t}from"commander";import ke from"chalk";async function k(o){if(!o){let r=await ee();return r||void 0}return await Q(o)}var fr=new _t().name("get").description("Get details of a CVM").argument("[app-id]","App ID of the CVM (optional)").option("-j, --json","Output in JSON format").action(async(o,r)=>{try{let t=await k(o),i=e.startSpinner(`Fetching CVM with App ID app_${t}`),n=await L(t);if(i.stop(!0),e.break(),n||(e.error(`CVM with App ID app_${t} not found`),process.exit(1)),r.json){console.log(JSON.stringify(n,null,2));return}e.keyValueTable({Name:n.name,"App ID":`app_${n.app_id}`,Status:n.status==="running"?ke.green(n.status):n.status==="stopped"?ke.red(n.status):ke.yellow(n.status),vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"App URL":`${y}/dashboard/cvms/app_${n.app_id}`})}catch(t){e.error(`Failed to get CVM details: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as St}from"commander";var gr=new St().name("start").description("Start a stopped CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let r=await k(o),t=e.startSpinner(`Starting CVM with App ID app_${r}`),i=await Te(r);t.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being started. You can check the dashboard for more details: ${y}/dashboard/cvms/app_${i.app_id}`)}catch(r){e.error(`Failed to start CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as bt}from"commander";var hr=new bt().name("stop").description("Stop a running CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let r=await k(o),t=e.startSpinner(`Stopping CVM with App ID app_${r}`),i=await Ve(r);t.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being stopped. You can check the dashboard for more details: ${y}/dashboard/cvms/app_${i.app_id}`)}catch(r){e.error(`Failed to stop CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Et}from"commander";var yr=new Et().name("restart").description("Restart a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let r=await k(o),t=e.startSpinner(`Restarting CVM with App ID app_${r}`),i=await Ue(r);t.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`,"App URL":i.app_url?i.app_url:`${y}/dashboard/cvms/app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being restarted. You can check the dashboard for more details: ${y}/dashboard/cvms/app_${i.app_id}`)}catch(r){e.error(`Failed to restart CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as $t}from"commander";import ie from"chalk";var vr=new $t().name("attestation").description("Get attestation information for a CVM").argument("[app-id]","CVM app ID (will prompt for selection if not provided)").option("-j, --json","Output in JSON format").action(async(o,r)=>{try{let t;if(o)t=await Q(o);else{e.info("No CVM specified, fetching available CVMs...");let n=await ee();if(!n)return;t=n}let i=e.startSpinner(`Fetching attestation information for CVM app_${t}...`);try{let n=await Le(t);if(i.stop(!0),!n||Object.keys(n).length===0){e.info("No attestation information found");return}if(r?.json){e.info(JSON.stringify(n,null,2));return}e.success("Attestation Summary:");let a={Status:n.is_online?ie.green("Online"):ie.red("Offline"),"Public Access":n.is_public?ie.green("Enabled"):ie.yellow("Disabled"),Error:n.error||"None",Certificates:`${n.app_certificates?.length||0} found`};if(e.keyValueTable(a,{borderStyle:"rounded"}),n.app_certificates&&n.app_certificates.length>0&&n.app_certificates.forEach((s,c)=>{e.break(),e.success(`Certificate #${c+1} (${s.position_in_chain===0?"End Entity":"CA"}):`);let l={Subject:`${s.subject.common_name||"Unknown"}${s.subject.organization?` (${s.subject.organization})`:""}`,Issuer:`${s.issuer.common_name||"Unknown"}${s.issuer.organization?` (${s.issuer.organization})`:""}`,"Serial Number":s.serial_number,Validity:`${new Date(s.not_before).toLocaleString()} to ${new Date(s.not_after).toLocaleString()}`,Fingerprint:s.fingerprint,"Signature Algorithm":s.signature_algorithm,"Is CA":s.is_ca?"Yes":"No","Position in Chain":s.position_in_chain};e.keyValueTable(l,{borderStyle:"rounded"})}),n.tcb_info){e.break(),e.success("Trusted Computing Base (TCB) Information:");let s={Mrtd:n.tcb_info.mrtd,"Rootfs Hash":n.tcb_info.rootfs_hash,Rtmr0:n.tcb_info.rtmr0,Rtmr1:n.tcb_info.rtmr1,Rtmr2:n.tcb_info.rtmr2,Rtmr3:n.tcb_info.rtmr3,"Event Log Entries":`${n.tcb_info.event_log.length} entries`};if(e.keyValueTable(s,{borderStyle:"rounded"}),n.tcb_info.event_log&&n.tcb_info.event_log.length>0){e.break(),e.success("Event Log (Showing entries to reproduce RTMR3):");let c=5,l=n.tcb_info.event_log.filter(m=>m.event!==null&&m.event!=="").map(m=>({Event:m.event,IMR:m.imr.toString(),"Event Type":m.event_type.toString(),Payload:m.event_payload}));e.table(l,[{key:"Event",header:"Event",minWidth:8},{key:"IMR",header:"IMR",minWidth:3},{key:"Event Type",header:"Type",minWidth:8},{key:"Payload",header:"Payload",minWidth:25}]),n.tcb_info.event_log.length>c&&e.info("To see all full attestation data, use --json"),e.break(),e.success("To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/")}}}catch(n){throw i.stop(!1),n}}catch(t){e.error(`Failed to get attestation information: ${t instanceof Error?t.message:String(t)}`)}});import{Command as Dt}from"commander";import{encryptEnvVars as It}from"@phala/dstack-sdk/encrypt-env-vars";import wr from"node:fs";import Pt from"node:path";import kr from"inquirer";import*as Cr from"node:fs";var J=(o,r)=>{let t={};if(o){for(let i of o)if(i.includes("=")){let[n,...a]=i.split("="),s=a.join("=");n&&(t[n]=s)}}if(r){let i=Cr.readFileSync(r,"utf8");for(let n of i.split(` `)){if(!n.trim()||n.trim().startsWith("#"))continue;let a=-1,s=!1,c="";for(let f=0;f<n.length;f++)if((n[f]==='"'||n[f]==="'"||n[f]==="`")&&(f===0||n[f-1]!=="\\"))s&&n[f]===c?(s=!1,c=""):s||(s=!0,c=n[f]);else if(n[f]==="="&&!s){a=f;break}else if(n[f]==="#"&&!s)break;if(a===-1){n.trim().startsWith("#");continue}let l=n.substring(0,a).trim(),m=n.substring(a+1),d=!1,g="",p=-1;for(let f=0;f<m.length;f++)if((m[f]==='"'||m[f]==="'"||m[f]==="`")&&(f===0||m[f-1]!=="\\"))d&&m[f]===g?(d=!1,g=""):d||(d=!0,g=m[f]);else if(m[f]==="#"&&!d&&f>0&&m[f-1]===" "){p=f-1;break}else if(m[f]==="#"&&!d&&f===0){p=f;break}p!==-1&&(m=m.substring(0,p)),m===void 0&&(m="");let u=m.charAt(0),v=m.charAt(m.length-1);u==='"'&&v==='"'||u==="'"&&v==="'"||u==="`"&&v==="`"?(m=m.substring(1,m.length-1),u==='"'&&(m=m.replace(/\\\\n/g,` `))):m=m.trim(),l&&(t[l]=m)}}return Object.entries(t).map(([i,n])=>({key:i,value:n}))};var _r=new Dt().name("create").description("Create a new CVM").option("-n, --name <name>","Name of the CVM").option("-c, --compose <compose>","Path to Docker Compose file").option("--vcpu <vcpu>",`Number of vCPUs, default is ${M}`).option("--memory <memory>",`Memory in MB, default is ${T}`).option("--disk-size <diskSize>",`Disk size in GB, default is ${V}`).option("--teepod-id <teepodId>","TEEPod ID to use. If not provided, it will be selected from the list of available TEEPods.").option("--image <image>","Version of dstack image to use. If not provided, it will be selected from the list of available images for the selected TEEPod.").option("-e, --env-file <envFile>","Path to environment file").option("--skip-env","Skip environment variable prompt",!1).option("--debug","Enable debug mode",!1).action(async o=>{try{if(!o.name){let{name:w}=await kr.prompt([{type:"input",name:"name",message:"Enter a name for the CVM:",validate:E=>E.trim()?E.trim().length>20?"CVM name must be less than 20 characters":E.trim().length<3?"CVM name must be at least 3 characters":/^[a-zA-Z0-9_-]+$/.test(E)?!0:"CVM name must contain only letters, numbers, underscores, and hyphens":"CVM name is required"}]);o.name=w}if(!o.compose){let E=K(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");o.compose=await $("Enter the path to your Docker Compose file:",E,"file")}let r=Pt.resolve(o.compose);wr.existsSync(r)||(e.error(`Docker Compose file not found: ${r}`),process.exit(1));let t=wr.readFileSync(r,"utf8");await N(),process.env.DSTACK_DOCKER_USERNAME&&process.env.DSTACK_DOCKER_PASSWORD?e.info("\u{1F510} Using private DockerHub registry credentials..."):process.env.DSTACK_AWS_ACCESS_KEY_ID&&process.env.DSTACK_AWS_SECRET_ACCESS_KEY&&process.env.DSTACK_AWS_REGION&&process.env.DSTACK_AWS_ECR_REGISTRY?e.info(`\u{1F510} Using private AWS ECR registry: ${process.env.DSTACK_AWS_ECR_REGISTRY}`):e.info("\u{1F510} Using public DockerHub registry...");let i=[];if(o.envFile)try{i=J([],o.envFile)}catch(w){e.error(`Failed to read environment file: ${w instanceof Error?w.message:String(w)}`),process.exit(1)}else if(!o.skipEnv){let{shouldSkip:w}=await kr.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!0}]);if(w)e.info("Skipping environment variable prompt");else{let E=await $("Enter the path to your environment file:",".env","file");i=J([],E)}}let n=Number(o.vcpu)||M,a=Number(o.memory)||T,s=Number(o.diskSize)||V;(Number.isNaN(n)||n<=0)&&(e.error(`Invalid number of vCPUs: ${n}`),process.exit(1)),(Number.isNaN(a)||a<=0)&&(e.error(`Invalid memory: ${a}`),process.exit(1)),(Number.isNaN(s)||s<=0)&&(e.error(`Invalid disk size: ${s}`),process.exit(1));let c=e.startSpinner("Fetching available TEEPods"),l=await O();c.stop(!0),l.nodes.length===0&&(e.error("No TEEPods available. Please try again later."),process.exit(1));let m;o.teepodId?(m=l.nodes.find(w=>w.teepod_id===Number(o.teepodId)),m||(e.error("Failed to find selected TEEPod"),process.exit(1))):(m=l.nodes[0],m||(e.error("Failed to find default TEEPod"),process.exit(1)));let d;o.image?(d=m.images?.find(w=>w.name===o.image),d||(e.error(`Failed to find selected image: ${o.image}`),process.exit(1))):(d=m.images?.find(w=>w.name===de),d||(e.error(`Failed to find default image ${de}`),process.exit(1)));let g={teepod_id:m.teepod_id,name:o.name,image:d.name,vcpu:n,memory:a,disk_size:s,compose_manifest:{docker_compose_file:t,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:o.name,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},p=e.startSpinner("Getting public key from CVM"),u=await Fe(g);p.stop(!0),u||(e.error("Failed to get public key from CVM"),process.exit(1));let v=e.startSpinner("Encrypting environment variables"),f=await It(i,u.app_env_encrypt_pubkey);v.stop(!0),o.debug&&(e.debug("Public key:",u.app_env_encrypt_pubkey),e.debug("Encrypted environment variables:",f),e.debug("Environment variables:",JSON.stringify(i)));let I=e.startSpinner("Creating CVM"),_=await Me({...g,encrypted_env:f,app_env_encrypt_pubkey:u.app_env_encrypt_pubkey,app_id_salt:u.app_id_salt});I.stop(!0),_||(e.error("Failed to create CVM"),process.exit(1)),e.success("CVM created successfully"),e.break();let se={"CVM ID":_.id,Name:_.name,Status:_.status,"App ID":`app_${_.app_id}`,"App URL":_.app_url?_.app_url:`${y}/dashboard/cvms/app_${_.app_id}`};e.keyValueTable(se,{borderStyle:"rounded"}),e.info(""),e.success(`Your CVM is being created. You can check its status with: phala cvms get app_${_.app_id}`)}catch(r){e.error(`Failed to create CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as At}from"commander";import xt from"inquirer";var Sr=new At().name("delete").description("Delete a CVM").argument("[app-id]","App ID of the CVM to delete (if not provided, a selection prompt will appear)").option("-f, --force","Skip confirmation prompt",!1).action(async(o,r)=>{try{let t=await k(o);if(!r.force){let{confirm:a}=await xt.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID app_${t}? This action cannot be undone.`,default:!1}]);if(!a){e.info("Deletion cancelled");return}}let i=e.startSpinner(`Deleting CVM app_${t}`),n=await Re(t);i.stop(!0),n||(e.error(`Failed to delete CVM app_${t}`),process.exit(1)),e.success(`CVM app_${t} deleted successfully`)}catch(t){e.error(`Failed to delete CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Ft}from"commander";import Mt from"node:fs";import{encryptEnvVars as Tt}from"@phala/dstack-sdk/encrypt-env-vars";var br=new Ft().name("upgrade").description("Upgrade a CVM to a new version").argument("[app-id]","CVM app ID to upgrade (will prompt for selection if not provided)").option("-c, --compose <compose>","Path to new Docker Compose file").option("-e, --env-file <envFile>","Path to environment file").option("--debug","Enable debug mode",!1).action(async(o,r)=>{try{let t=await k(o),i=e.startSpinner(`Fetching current configuration for CVM app_${t}`),n=