phala 0.0.1-alpha-8 → 0.0.1-alpha-10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- var Dr=Object.defineProperty;var Fr=(t,e,r)=>e in t?Dr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var Je=(t,e,r)=>(Fr(t,typeof e!="symbol"?e+"":e,r),r);import{Command as Qo}from"commander";import Ye from"chalk";var Xe=Ye.hex("#cdfa50"),Qe=Xe(`
2
+ var yr=Object.defineProperty;var vr=(t,e,r)=>e in t?yr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var Ge=(t,e,r)=>(vr(t,typeof e!="symbol"?e+"":e,r),r);import{Command as Io}from"commander";import Ke from"chalk";var He=Ke.hex("#cdfa50"),qe=He(`
3
3
  \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
4
4
  \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
5
5
  \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
@@ -21,7 +21,7 @@ var Dr=Object.defineProperty;var Fr=(t,e,r)=>e in t?Dr(t,e,{enumerable:!0,config
21
21
  \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
22
22
  \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
23
23
  \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
24
- `),on=Xe(`
24
+ `),Lo=He(`
25
25
  \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
26
26
  \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
27
27
  \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
@@ -43,7 +43,7 @@ var Dr=Object.defineProperty;var Fr=(t,e,r)=>e in t?Dr(t,e,{enumerable:!0,config
43
43
  \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
44
44
  \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
45
45
  \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
46
- `),nn=Ye.cyan("PHALA TEE CLOUD CLI");import{Command as to}from"commander";import{Command as Yr}from"commander";import L from"fs";import Re from"path";import Z from"os";import be from"crypto";import S from"chalk";function Ar(t){let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return t.replace(new RegExp(e,"g"),"")}function q(t){return Ar(t).length}function re(t,e){if(!t)return[""];if(q(t)<=e)return[t];let r=[],n="",i=0,a=t.split(/(\s+)/).filter(c=>c.trim().length>0);for(let c of a){let p=q(c);if(p>e){n&&(r.push(n),n="",i=0),r.push(c);continue}i+p+(i>0?1:0)>e?(r.push(n),n=c,i=p):n?(n=`${n} ${c}`,i+=p+1):(n=c,i=p)}return n&&r.push(n),r}var o={error:(t,...e)=>{console.error(S.red("\u2717"),S.red(t),...e)},warn:(t,...e)=>{console.log(S.yellow("\u26A0"),S.yellow(t),...e)},info:(t,...e)=>{console.log(S.blue("\u2139"),S.blue(t),...e)},success:(t,...e)=>{console.log(S.green("\u2713"),S.green(t),...e)},debug:(t,...e)=>{process.env.DEBUG&&console.log(S.gray("\u{1F50D}"),S.gray(t),...e)},table:(t,e)=>{if(t.length===0){console.log(S.yellow("No data to display"));return}if(e)if(typeof e[0]=="string"){let r=e.map(n=>({key:n,header:n.charAt(0).toUpperCase()+n.slice(1)}));Ae(t,{columns:r,borderStyle:"rounded",headerStyle:n=>S.cyan.bold(n)})}else Ae(t,{columns:e,borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)});else Ae(t,{borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)})},keyValueTable:(t,e)=>{let n={...{borderStyle:"rounded",enableTextWrapping:!0,maxDepth:2,formatKeys:!0,keyFormatter:k=>{let E=["URL","ID","API","UI","URI","CPU","GPU","RAM","JSON","XML","HTML","HTTP","HTTPS","SSH","FTP","IP","TCP","UDP","DNS","SSL","TLS","SQL","VCPU","CVM","TEE","IO"],P={teepod:"TEEPod",dstack:"Dstack"},V;k.includes("_")?V=k.split("_").map(I=>I.charAt(0).toUpperCase()+I.slice(1).toLowerCase()).join(" "):k.includes("-")?V=k.split("-").map(I=>I.charAt(0).toUpperCase()+I.slice(1).toLowerCase()).join(" "):V=k.charAt(0).toUpperCase()+k.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let I of E){let U=new RegExp(`\\b${I.toLowerCase()}\\b`,"gi");V=V.replace(U,I)}for(let[I,U]of Object.entries(P)){let Ce=new RegExp(`\\b${I}\\b`,"gi");V=V.replace(Ce,U)}return V},valueFormatter:k=>String(k??"")},...e},{include:i,exclude:a,keyFormatter:c,valueFormatter:p,formatKeys:u,keyWidth:d,valueWidth:v,borderStyle:y,enableTextWrapping:m,maxDepth:l}=n,f=Object.keys(t);if(i&&(f=f.filter(k=>i.includes(k))),a&&(f=f.filter(k=>!a.includes(k))),f.length===0){console.log(S.yellow("No properties to display"));return}let h=f.map(k=>{let E=t[k],P;return E==null?P="":typeof E=="object"&&!Array.isArray(E)?P=et(E,0,l):Array.isArray(E)?E.length===0?P="[]":typeof E[0]=="object"?P=`[${E.length} items]`:P=`[${E.join(", ")}]`:P=String(E),p&&(P=p(E,k)),{key:u&&c?c(k):k,value:P}}),C=tt(),g=d,b=v;if(g||(g=Math.max(...h.map(k=>q(k.key)),10),g=Math.min(g,Math.floor(C/3))),!b){b=Math.max(...h.map(P=>q(P.value)),10),b+=3;let k=7,E=C-g-k;b=Math.min(b,E)}let w=Ir(y),W=`${w.topLeft}${w.horizontal.repeat(g+2)}${w.topT}${w.horizontal.repeat(b+2)}${w.topRight}`,N=`${w.leftT}${w.horizontal.repeat(g+2)}${w.cross}${w.horizontal.repeat(b+2)}${w.rightT}`;console.log(W),console.log(N),h.forEach((k,E)=>{let P=m?re(k.key,g):[k.key],V=m?re(k.value,b):[k.value],I=Math.max(P.length,V.length);for(let U=0;U<I;U++){let Ce=P[U]||"",Ze=V[U]||"",Tr=Ce+" ".repeat(Math.max(0,g-q(Ce))),Pr=Ze+" ".repeat(Math.max(0,b-q(Ze)));console.log(`${w.vertical} ${Tr} ${w.vertical} ${Pr} ${w.vertical}`)}E<h.length-1&&console.log(`${w.leftT}${w.horizontal.repeat(g+2)}${w.cross}${w.horizontal.repeat(b+2)}${w.rightT}`)});let Fe=`${w.bottomLeft}${w.horizontal.repeat(g+2)}${w.bottomT}${w.horizontal.repeat(b+2)}${w.bottomRight}`;console.log(Fe)},startSpinner:t=>(process.stdout.write(`${S.blue("\u27F3")} ${t}... `),{stop:(e=!0,r)=>{let n=e?S.green("\u2713"):S.red("\u2717"),i=r?`: ${r}`:"";console.log(`${n}${i}`)}}),break(){console.log("")}};function et(t,e,r){if(e>=r)return"[Nested Object]";if(t==null)return"";if(Array.isArray(t))return t.length===0?"[]":`[${t.length} items]`;let n=[];for(let[i,a]of Object.entries(t))a==null?n.push(`${i}: `):typeof a=="object"?n.push(`${i}: ${et(a,e+1,r)}`):n.push(`${i}: ${a}`);return n.join(", ")}function Ir(t="single"){return{single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[t]}function tt(){return process.stdout.columns||80}function Rr(t,e,r={}){let n=tt(),i=r.borderChars??3,c=(r.additionalBorderWidth??1)+e.length*i,p=n-c,u={},d=0,v=0;for(let l of e){let f=l.key;if(l.fixedWidth!==void 0){u[f]=l.fixedWidth,d+=l.fixedWidth;continue}let h=l.minWidth??l.header.length,C;l.getWidth?C=Math.max(h,l.header.length,...t.map(g=>l.getWidth(g))):l.getValue?C=Math.max(h,l.header.length,...t.map(g=>String(l.getValue(g)||"").length)):C=Math.max(h,l.header.length,...t.map(g=>String(g[l.key]||"").length)),u[f]=C,d+=C,v+=l.weight??1}let y=Math.max(0,p-d);if(y>0&&v>0)for(let l of e){let f=l.key;if(l.fixedWidth===void 0&&l.weight){let h=Math.floor(y*(l.weight/v));u[f]+=h}}let m=Object.values(u).reduce((l,f)=>l+f,0)+c;if(m>n){let l=p/(m-c),f={};for(let h of e){let C=h.key,g=h.minWidth??h.header.length;f[C]=Math.max(g,Math.floor(u[C]*l))}return f}return u}function Ae(t,e={}){if(e.keyValueMode&&t.length===1){let m=t[0],l=[];e.columns||(e.columns=Object.keys(m).map(f=>({key:f,header:f.charAt(0).toUpperCase()+f.slice(1).replace(/([A-Z])/g," $1")})));for(let f of e.columns){let h=String(f.key),C;if(f.accessor)C=f.accessor(m);else if(typeof f.key=="string"&&f.key.includes(".")){let g=f.key.split("."),b=m;for(let w of g){if(b==null){C="";break}b=b[w]}C=b}else C=m[f.key];f.formatter&&(C=f.formatter(C)),l.push({key:f.header||h,value:C})}t=l,e.columns=[{key:"key",minWidth:15},{key:"value",minWidth:20}]}if(t.length===0){console.log(S.yellow("No data to display"));return}let n={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:m=>S.bold(m),cellStyle:m=>m,enableTextWrapping:!0},...e},i=n.columns;if(i)i=i.map(m=>({...m,enableTextWrapping:m.enableTextWrapping!==void 0?m.enableTextWrapping:n.enableTextWrapping}));else{let m=t[0];i=Object.keys(m).map(l=>({key:l,header:l.charAt(0).toUpperCase()+l.slice(1),enableTextWrapping:n.enableTextWrapping}))}let c={single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[n.borderStyle],p=i.map(m=>({key:m.key,header:m.header||String(m.key),minWidth:m.minWidth||3,weight:m.weight,enableTextWrapping:m.enableTextWrapping,getValue:m.accessor?l=>m.accessor(l):l=>{if(typeof m.key=="string"&&m.key.includes(".")){let f=m.key.split("."),h=l;for(let C of f){if(h==null)return"";h=h[C]}return h??""}return l[m.key]??""}})),u=Rr(t,p),d=i.map((m,l)=>({...m,width:u[p[l].key]})),v=d.map(m=>m.header||String(m.key)),y=(m,l)=>{let f=d.map(g=>{let b;if(g.accessor)b=g.accessor(m);else if(typeof g.key=="string"&&g.key.includes(".")){let W=g.key.split("."),N=m;for(let Fe of W){if(N==null){b="";break}N=N[Fe]}b=N??""}else b=m[g.key]??"";let w=g.formatter?g.formatter(b):String(b||"");return g.enableTextWrapping?{lines:re(w,g.width),key:String(g.key)}:{lines:[w.length>g.width?w.substring(0,g.width-1)+"\u2026":w],key:String(g.key)}}),h=Math.max(...f.map(g=>g.lines.length)),C=[];for(let g=0;g<h;g++){let b=f.map((w,W)=>{let N=w.lines[g]||"";return n.cellStyle(N.padEnd(d[W].width),l,w.key)});C.push(b)}return C};if(n.border){let m=c.topLeft+d.map(f=>c.horizontal.repeat(f.width+2)).join(c.topT)+c.topRight;if(console.log(m),n.includeHeaders){let f=d.map((g,b)=>({lines:g.enableTextWrapping?re(v[b],g.width):[v[b]],width:g.width})),h=Math.max(...f.map(g=>g.lines.length));for(let g=0;g<h;g++){let b=c.vertical+f.map(w=>{let W=w.lines[g]||"";return" "+n.headerStyle(W.padEnd(w.width))+" "}).join(c.vertical)+c.vertical;console.log(b)}let C=c.leftT+d.map(g=>c.horizontal.repeat(g.width+2)).join(c.cross)+c.rightT;console.log(C)}t.forEach((f,h)=>{let C=y(f,h);if(C.forEach(g=>{console.log(c.vertical+g.map(b=>` ${b} `).join(c.vertical)+c.vertical)}),h<t.length-1&&C.length>1){let g=c.leftT+d.map(b=>c.horizontal.repeat(b.width+2)).join(c.cross)+c.rightT;console.log(g)}});let l=c.bottomLeft+d.map(f=>c.horizontal.repeat(f.width+2)).join(c.bottomT)+c.bottomRight;console.log(l)}else{if(n.includeHeaders){let m=d.map((h,C)=>({lines:h.enableTextWrapping?re(v[C],h.width):[v[C]],width:h.width})),l=Math.max(...m.map(h=>h.lines.length));for(let h=0;h<l;h++){let C=m.map(g=>{let b=g.lines[h]||"";return n.headerStyle(b.padEnd(g.width))}).join(" ");console.log(C)}let f=d.map(h=>"\u2500".repeat(h.width)).join(" ");console.log(f)}t.forEach((m,l)=>{let f=y(m,l);f.forEach(h=>{console.log(h.join(" "))}),l<t.length-1&&f.length>1&&console.log("")})}console.log(`Total: ${t.length} rows`)}var oe=Re.join(Z.homedir(),".phala-cloud"),ne=Re.join(oe,"api-key"),Ie=Re.join(oe,"docker-credentials.json");function rt(){if(!L.existsSync(oe))try{L.mkdirSync(oe,{recursive:!0})}catch(t){throw o.error(`Failed to create directory ${oe}:`,t),t}}function ot(){let t=[Z.hostname(),Z.platform(),Z.arch(),Z.cpus()[0]?.model||"",Z.userInfo().username],e=be.createHash("sha256");return e.update(t.join("|")),e.digest()}function Mr(t){try{let e=ot(),r=be.randomBytes(16),n=be.createCipheriv("aes-256-cbc",e.slice(0,32),r),i=n.update(t,"utf8","hex");return i+=n.final("hex"),r.toString("hex")+":"+i}catch(e){throw o.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function Vr(t){try{let e=ot(),r=t.split(":");if(r.length!==2)throw new Error("Invalid encrypted format");let n=Buffer.from(r[0],"hex"),i=r[1],a=be.createDecipheriv("aes-256-cbc",e.slice(0,32),n),c=a.update(i,"hex","utf8");return c+=a.final("utf8"),c}catch(e){throw o.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function nt(t){rt();try{let e=Mr(t);L.writeFileSync(ne,e,{mode:384})}catch(e){throw o.error("Failed to save API key:",e),e}}async function we(){try{if(L.existsSync(ne)){let t=L.readFileSync(ne,"utf8").trim();return Vr(t)}return null}catch(t){return o.error("Failed to read API key:",t),null}}async function ie(){try{L.existsSync(ne)?(L.unlinkSync(ne),o.success("API key removed successfully.")):o.warn("No API key found to remove.")}catch(t){throw o.error("Failed to remove API key:",t),t}}async function it(t){rt();try{L.writeFileSync(Ie,JSON.stringify(t,null,2),{mode:384}),o.success("Docker information saved successfully.")}catch(e){throw o.error("Failed to save Docker information:",e),e}}async function O(){try{if(L.existsSync(Ie)){let t=L.readFileSync(Ie,"utf8");return JSON.parse(t)}return null}catch(t){return o.error("Failed to read Docker credentials:",t),null}}import Xr from"prompts";import Lr from"axios";var Me=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",J=process.env.CLOUD_URL||"https://cloud.phala.network",st="0.0.1",at="https://hub.docker.com/v2",ct="phalanetwork/tappd-simulator:latest",se=2,ae=4096,ce=40,mt="3",lt="dstack-0.3.5",x={USER_INFO:"/api/v1/auth/me",TEEPODS:"/api/v1/teepods/available",TEEPOD_IMAGES:t=>`/api/v1/teepods/${t}/images`,CVMS:t=>`/api/v1/cvms?user_id=${t}`,CVM_BY_APP_ID:t=>`/api/v1/cvms/app_${t}`,CVM_START:t=>`/api/v1/cvms/app_${t}/start`,CVM_STOP:t=>`/api/v1/cvms/app_${t}/stop`,CVM_RESTART:t=>`/api/v1/cvms/app_${t}/restart`,CVM_LOGS:t=>`/api/v1/cvms/app_${t}/logs`,CVM_FROM_CONFIGURATION:"/api/v1/cvms/from_cvm_configuration",CVM_PUBKEY:"/api/v1/cvms/pubkey/from_cvm_configuration",CVM_UPGRADE:t=>`/api/v1/cvms/app_${t}/compose`,CVM_ATTESTATION:t=>`/api/v1/cvms/app_${t}/attestation`,CVM_RESIZE:t=>`/api/v1/cvms/app_${t}/resources`},pt=`version: '3.8'
46
+ `),No=Ke.cyan("PHALA TEE CLOUD CLI");import{Command as jr}from"commander";import{Command as Nr}from"commander";import L from"fs";import Ae from"path";import Z from"os";import be from"crypto";import S from"chalk";function br(t){let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return t.replace(new RegExp(e,"g"),"")}function q(t){return br(t).length}function re(t,e){if(!t)return[""];if(q(t)<=e)return[t];let r=[],n="",i=0,a=t.split(/(\s+)/).filter(c=>c.trim().length>0);for(let c of a){let p=q(c);if(p>e){n&&(r.push(n),n="",i=0),r.push(c);continue}i+p+(i>0?1:0)>e?(r.push(n),n=c,i=p):n?(n=`${n} ${c}`,i+=p+1):(n=c,i=p)}return n&&r.push(n),r}var o={error:(t,...e)=>{console.error(S.red("\u2717"),S.red(t),...e)},warn:(t,...e)=>{console.log(S.yellow("\u26A0"),S.yellow(t),...e)},info:(t,...e)=>{console.log(S.blue("\u2139"),S.blue(t),...e)},success:(t,...e)=>{console.log(S.green("\u2713"),S.green(t),...e)},debug:(t,...e)=>{process.env.DEBUG&&console.log(S.gray("\u{1F50D}"),S.gray(t),...e)},table:(t,e)=>{if(t.length===0){console.log(S.yellow("No data to display"));return}if(e)if(typeof e[0]=="string"){let r=e.map(n=>({key:n,header:n.charAt(0).toUpperCase()+n.slice(1)}));Pe(t,{columns:r,borderStyle:"rounded",headerStyle:n=>S.cyan.bold(n)})}else Pe(t,{columns:e,borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)});else Pe(t,{borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)})},keyValueTable:(t,e)=>{let n={...{borderStyle:"rounded",enableTextWrapping:!0,maxDepth:2,formatKeys:!0,keyFormatter:k=>{let E=["URL","ID","API","UI","URI","CPU","GPU","RAM","JSON","XML","HTML","HTTP","HTTPS","SSH","FTP","IP","TCP","UDP","DNS","SSL","TLS","SQL","VCPU","CVM","TEE","IO"],D={teepod:"TEEPod",dstack:"Dstack"},V;k.includes("_")?V=k.split("_").map(I=>I.charAt(0).toUpperCase()+I.slice(1).toLowerCase()).join(" "):k.includes("-")?V=k.split("-").map(I=>I.charAt(0).toUpperCase()+I.slice(1).toLowerCase()).join(" "):V=k.charAt(0).toUpperCase()+k.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let I of E){let U=new RegExp(`\\b${I.toLowerCase()}\\b`,"gi");V=V.replace(U,I)}for(let[I,U]of Object.entries(D)){let ve=new RegExp(`\\b${I}\\b`,"gi");V=V.replace(ve,U)}return V},valueFormatter:k=>String(k??"")},...e},{include:i,exclude:a,keyFormatter:c,valueFormatter:p,formatKeys:u,keyWidth:d,valueWidth:v,borderStyle:y,enableTextWrapping:m,maxDepth:l}=n,f=Object.keys(t);if(i&&(f=f.filter(k=>i.includes(k))),a&&(f=f.filter(k=>!a.includes(k))),f.length===0){console.log(S.yellow("No properties to display"));return}let h=f.map(k=>{let E=t[k],D;return E==null?D="":typeof E=="object"&&!Array.isArray(E)?D=Ze(E,0,l):Array.isArray(E)?E.length===0?D="[]":typeof E[0]=="object"?D=`[${E.length} items]`:D=`[${E.join(", ")}]`:D=String(E),p&&(D=p(E,k)),{key:u&&c?c(k):k,value:D}}),b=Je(),g=d,C=v;if(g||(g=Math.max(...h.map(k=>q(k.key)),10),g=Math.min(g,Math.floor(b/3))),!C){C=Math.max(...h.map(D=>q(D.value)),10),C+=3;let k=7,E=b-g-k;C=Math.min(C,E)}let w=Cr(y),W=`${w.topLeft}${w.horizontal.repeat(g+2)}${w.topT}${w.horizontal.repeat(C+2)}${w.topRight}`,N=`${w.leftT}${w.horizontal.repeat(g+2)}${w.cross}${w.horizontal.repeat(C+2)}${w.rightT}`;console.log(W),console.log(N),h.forEach((k,E)=>{let D=m?re(k.key,g):[k.key],V=m?re(k.value,C):[k.value],I=Math.max(D.length,V.length);for(let U=0;U<I;U++){let ve=D[U]||"",Be=V[U]||"",gr=ve+" ".repeat(Math.max(0,g-q(ve))),hr=Be+" ".repeat(Math.max(0,C-q(Be)));console.log(`${w.vertical} ${gr} ${w.vertical} ${hr} ${w.vertical}`)}E<h.length-1&&console.log(`${w.leftT}${w.horizontal.repeat(g+2)}${w.cross}${w.horizontal.repeat(C+2)}${w.rightT}`)});let Te=`${w.bottomLeft}${w.horizontal.repeat(g+2)}${w.bottomT}${w.horizontal.repeat(C+2)}${w.bottomRight}`;console.log(Te)},startSpinner:t=>(process.stdout.write(`${S.blue("\u27F3")} ${t}... `),{stop:(e=!0,r)=>{let n=e?S.green("\u2713"):S.red("\u2717"),i=r?`: ${r}`:"";console.log(`${n}${i}`)}}),break(){console.log("")}};function Ze(t,e,r){if(e>=r)return"[Nested Object]";if(t==null)return"";if(Array.isArray(t))return t.length===0?"[]":`[${t.length} items]`;let n=[];for(let[i,a]of Object.entries(t))a==null?n.push(`${i}: `):typeof a=="object"?n.push(`${i}: ${Ze(a,e+1,r)}`):n.push(`${i}: ${a}`);return n.join(", ")}function Cr(t="single"){return{single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[t]}function Je(){return process.stdout.columns||80}function wr(t,e,r={}){let n=Je(),i=r.borderChars??3,c=(r.additionalBorderWidth??1)+e.length*i,p=n-c,u={},d=0,v=0;for(let l of e){let f=l.key;if(l.fixedWidth!==void 0){u[f]=l.fixedWidth,d+=l.fixedWidth;continue}let h=l.minWidth??l.header.length,b;l.getWidth?b=Math.max(h,l.header.length,...t.map(g=>l.getWidth(g))):l.getValue?b=Math.max(h,l.header.length,...t.map(g=>String(l.getValue(g)||"").length)):b=Math.max(h,l.header.length,...t.map(g=>String(g[l.key]||"").length)),u[f]=b,d+=b,v+=l.weight??1}let y=Math.max(0,p-d);if(y>0&&v>0)for(let l of e){let f=l.key;if(l.fixedWidth===void 0&&l.weight){let h=Math.floor(y*(l.weight/v));u[f]+=h}}let m=Object.values(u).reduce((l,f)=>l+f,0)+c;if(m>n){let l=p/(m-c),f={};for(let h of e){let b=h.key,g=h.minWidth??h.header.length;f[b]=Math.max(g,Math.floor(u[b]*l))}return f}return u}function Pe(t,e={}){if(e.keyValueMode&&t.length===1){let m=t[0],l=[];e.columns||(e.columns=Object.keys(m).map(f=>({key:f,header:f.charAt(0).toUpperCase()+f.slice(1).replace(/([A-Z])/g," $1")})));for(let f of e.columns){let h=String(f.key),b;if(f.accessor)b=f.accessor(m);else if(typeof f.key=="string"&&f.key.includes(".")){let g=f.key.split("."),C=m;for(let w of g){if(C==null){b="";break}C=C[w]}b=C}else b=m[f.key];f.formatter&&(b=f.formatter(b)),l.push({key:f.header||h,value:b})}t=l,e.columns=[{key:"key",minWidth:15},{key:"value",minWidth:20}]}if(t.length===0){console.log(S.yellow("No data to display"));return}let n={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:m=>S.bold(m),cellStyle:m=>m,enableTextWrapping:!0},...e},i=n.columns;if(i)i=i.map(m=>({...m,enableTextWrapping:m.enableTextWrapping!==void 0?m.enableTextWrapping:n.enableTextWrapping}));else{let m=t[0];i=Object.keys(m).map(l=>({key:l,header:l.charAt(0).toUpperCase()+l.slice(1),enableTextWrapping:n.enableTextWrapping}))}let c={single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[n.borderStyle],p=i.map(m=>({key:m.key,header:m.header||String(m.key),minWidth:m.minWidth||3,weight:m.weight,enableTextWrapping:m.enableTextWrapping,getValue:m.accessor?l=>m.accessor(l):l=>{if(typeof m.key=="string"&&m.key.includes(".")){let f=m.key.split("."),h=l;for(let b of f){if(h==null)return"";h=h[b]}return h??""}return l[m.key]??""}})),u=wr(t,p),d=i.map((m,l)=>({...m,width:u[p[l].key]})),v=d.map(m=>m.header||String(m.key)),y=(m,l)=>{let f=d.map(g=>{let C;if(g.accessor)C=g.accessor(m);else if(typeof g.key=="string"&&g.key.includes(".")){let W=g.key.split("."),N=m;for(let Te of W){if(N==null){C="";break}N=N[Te]}C=N??""}else C=m[g.key]??"";let w=g.formatter?g.formatter(C):String(C||"");return g.enableTextWrapping?{lines:re(w,g.width),key:String(g.key)}:{lines:[w.length>g.width?w.substring(0,g.width-1)+"\u2026":w],key:String(g.key)}}),h=Math.max(...f.map(g=>g.lines.length)),b=[];for(let g=0;g<h;g++){let C=f.map((w,W)=>{let N=w.lines[g]||"";return n.cellStyle(N.padEnd(d[W].width),l,w.key)});b.push(C)}return b};if(n.border){let m=c.topLeft+d.map(f=>c.horizontal.repeat(f.width+2)).join(c.topT)+c.topRight;if(console.log(m),n.includeHeaders){let f=d.map((g,C)=>({lines:g.enableTextWrapping?re(v[C],g.width):[v[C]],width:g.width})),h=Math.max(...f.map(g=>g.lines.length));for(let g=0;g<h;g++){let C=c.vertical+f.map(w=>{let W=w.lines[g]||"";return" "+n.headerStyle(W.padEnd(w.width))+" "}).join(c.vertical)+c.vertical;console.log(C)}let b=c.leftT+d.map(g=>c.horizontal.repeat(g.width+2)).join(c.cross)+c.rightT;console.log(b)}t.forEach((f,h)=>{let b=y(f,h);if(b.forEach(g=>{console.log(c.vertical+g.map(C=>` ${C} `).join(c.vertical)+c.vertical)}),h<t.length-1&&b.length>1){let g=c.leftT+d.map(C=>c.horizontal.repeat(C.width+2)).join(c.cross)+c.rightT;console.log(g)}});let l=c.bottomLeft+d.map(f=>c.horizontal.repeat(f.width+2)).join(c.bottomT)+c.bottomRight;console.log(l)}else{if(n.includeHeaders){let m=d.map((h,b)=>({lines:h.enableTextWrapping?re(v[b],h.width):[v[b]],width:h.width})),l=Math.max(...m.map(h=>h.lines.length));for(let h=0;h<l;h++){let b=m.map(g=>{let C=g.lines[h]||"";return n.headerStyle(C.padEnd(g.width))}).join(" ");console.log(b)}let f=d.map(h=>"\u2500".repeat(h.width)).join(" ");console.log(f)}t.forEach((m,l)=>{let f=y(m,l);f.forEach(h=>{console.log(h.join(" "))}),l<t.length-1&&f.length>1&&console.log("")})}console.log(`Total: ${t.length} rows`)}var oe=Ae.join(Z.homedir(),".phala-cloud"),ne=Ae.join(oe,"api-key"),De=Ae.join(oe,"docker-credentials.json");function Ye(){if(!L.existsSync(oe))try{L.mkdirSync(oe,{recursive:!0})}catch(t){throw o.error(`Failed to create directory ${oe}:`,t),t}}function Xe(){let t=[Z.hostname(),Z.platform(),Z.arch(),Z.cpus()[0]?.model||"",Z.userInfo().username],e=be.createHash("sha256");return e.update(t.join("|")),e.digest()}function kr(t){try{let e=Xe(),r=be.randomBytes(16),n=be.createCipheriv("aes-256-cbc",e.slice(0,32),r),i=n.update(t,"utf8","hex");return i+=n.final("hex"),r.toString("hex")+":"+i}catch(e){throw o.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function Sr(t){try{let e=Xe(),r=t.split(":");if(r.length!==2)throw new Error("Invalid encrypted format");let n=Buffer.from(r[0],"hex"),i=r[1],a=be.createDecipheriv("aes-256-cbc",e.slice(0,32),n),c=a.update(i,"hex","utf8");return c+=a.final("utf8"),c}catch(e){throw o.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function Qe(t){Ye();try{let e=kr(t);L.writeFileSync(ne,e,{mode:384})}catch(e){throw o.error("Failed to save API key:",e),e}}async function Ce(){try{if(L.existsSync(ne)){let t=L.readFileSync(ne,"utf8").trim();return Sr(t)}return null}catch(t){return o.error("Failed to read API key:",t),null}}async function ie(){try{L.existsSync(ne)?(L.unlinkSync(ne),o.success("API key removed successfully.")):o.warn("No API key found to remove.")}catch(t){throw o.error("Failed to remove API key:",t),t}}async function et(t){Ye();try{L.writeFileSync(De,JSON.stringify(t,null,2),{mode:384}),o.success("Docker information saved successfully.")}catch(e){throw o.error("Failed to save Docker information:",e),e}}async function O(){try{if(L.existsSync(De)){let t=L.readFileSync(De,"utf8");return JSON.parse(t)}return null}catch(t){return o.error("Failed to read Docker credentials:",t),null}}import Or from"prompts";import Er from"axios";var Fe=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",J=process.env.CLOUD_URL||"https://cloud.phala.network",tt="0.0.1",rt="https://hub.docker.com/v2",ot="phalanetwork/tappd-simulator:latest",se=2,ae=4096,ce=40,nt="3",it="dstack-0.3.5",x={USER_INFO:"/api/v1/auth/me",TEEPODS:"/api/v1/teepods/available",TEEPOD_IMAGES:t=>`/api/v1/teepods/${t}/images`,CVMS:t=>`/api/v1/cvms?user_id=${t}`,CVM_BY_APP_ID:t=>`/api/v1/cvms/app_${t}`,CVM_START:t=>`/api/v1/cvms/app_${t}/start`,CVM_STOP:t=>`/api/v1/cvms/app_${t}/stop`,CVM_RESTART:t=>`/api/v1/cvms/app_${t}/restart`,CVM_LOGS:t=>`/api/v1/cvms/app_${t}/logs`,CVM_FROM_CONFIGURATION:"/api/v1/cvms/from_cvm_configuration",CVM_PUBKEY:"/api/v1/cvms/pubkey/from_cvm_configuration",CVM_UPGRADE:t=>`/api/v1/cvms/app_${t}/compose`,CVM_ATTESTATION:t=>`/api/v1/cvms/app_${t}/attestation`,CVM_RESIZE:t=>`/api/v1/cvms/app_${t}/resources`},st=`version: '3.8'
47
47
  services:
48
48
  postgres:
49
49
  image: postgres:15
@@ -88,7 +88,7 @@ networks:
88
88
  driver: bridge
89
89
 
90
90
  volumes:
91
- postgres-data:`,ut=`version: '3.8'
91
+ postgres-data:`,at=`version: '3.8'
92
92
  services:
93
93
  app:
94
94
  image: {{imageName}}:{{tag}}
@@ -99,20 +99,20 @@ services:
99
99
  {{#each envVars}} - {{{this}}}
100
100
  {{/each}}
101
101
  restart: always
102
- `;function Ve(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var Le=class{client;apiKey=null;constructor(e){o.debug(`Creating API client with base URL: ${e}`),this.client=Lr.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${st}`}}),this.client.interceptors.request.use(async r=>{if(!this.apiKey){if(this.apiKey=await we(),!this.apiKey)throw new Error('API key not found. Please set an API key first with "phala auth login"');o.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return r.headers["X-API-Key"]=this.apiKey,o.debug(`Making request to: ${r.baseURL}${r.url}`),r}),this.client.interceptors.response.use(r=>(o.debug(`Received successful response from: ${r.config.url}`),r),r=>{if(r.response){let{status:n,data:i}=r.response;o.debug(`Received error response: ${n} - ${Ve(i)}`),n===401?o.error("Authentication failed. Please check your API key."):n===403?o.error("You do not have permission to perform this action."):n===404?o.error("Resource not found."):o.error(`API Error (${n}): ${i.message||Ve(i)}`)}else r.request?(o.error("No response received from the server. Please check your internet connection."),o.debug(`Request details: ${Ve(r.request).substring(0,200)}...`)):o.error(`Error: ${r.message}`);return Promise.reject(r)})}async get(e,r){try{return o.debug(`GET request to: ${e}`),(await this.client.get(e,r)).data}catch(n){throw o.debug(`GET request failed: ${n instanceof Error?n.message:String(n)}`),n}}async post(e,r,n){try{return o.debug(`POST request to: ${e}`),(await this.client.post(e,r,n)).data}catch(i){throw o.debug(`POST request failed: ${i instanceof Error?i.message:String(i)}`),i}}async put(e,r,n){try{return o.debug(`PUT request to: ${e}`),(await this.client.put(e,r,n)).data}catch(i){throw o.debug(`PUT request failed: ${i instanceof Error?i.message:String(i)}`),i}}async delete(e,r){try{return o.debug(`DELETE request to: ${e}`),(await this.client.delete(e,r)).data}catch(n){throw o.debug(`DELETE request failed: ${n instanceof Error?n.message:String(n)}`),n}}async patch(e,r,n){try{return o.debug(`PATCH request to: ${e}`),(await this.client.patch(e,r,n)).data}catch(i){throw o.debug(`PATCH request failed: ${i instanceof Error?i.message:String(i)}`),i}}};o.debug(`Initializing API client with URL: ${Me}`);var $=new Le(Me);import{z as s}from"zod";import{INVALID as Nr,ParseStatus as Or,ZodIssueCode as Y,ZodParsedType as dt,ZodType as Ur,addIssueToContext as X,z as ft}from"zod";var zr="ZodDecimal",jr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,le=class extends Ur{_parse(e){if(e.data!==null&&typeof e.data=="object"&&"toNumber"in e.data&&(e.data=e.data.toNumber()),this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==dt.number){let a=this._getOrReturnCtx(e);return X(a,{code:Y.invalid_type,expected:dt.number,received:a.parsedType}),Nr}let n,i=new Or;for(let a of this._def.checks)if(a.kind==="precision"){let c=e.data.toString().match(jr);Math.max((c[1]?c[1].length:0)-(c[2]?parseInt(c[2],10):0),0)>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.custom,message:a.message,params:{precision:a.value}}),i.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.custom,message:a.message,params:{wholeNumber:a.value}}),i.dirty()):a.kind==="min"?(a.inclusive?e.data<a.value:e.data<=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.too_small,minimum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="max"?(a.inclusive?e.data>a.value:e.data>=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="finite"&&(Number.isFinite(e.data)||(n=this._getOrReturnCtx(e,n),X(n,{code:Y.not_finite,message:a.message}),i.dirty()));return{status:i.value,value:e.data}}setLimit(e,r,n,i){return new le({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:n,message:i}]})}_addCheck(e){return new le({...this._def,checks:[...this._def.checks,e]})}lte(e,r){return this.setLimit("max",e,!0,r)}lt(e,r){return this.setLimit("max",e,!1,r)}max=this.lte;gt(e,r){return this.setLimit("min",e,!1,r)}gte(e,r){return this.setLimit("min",e,!0,r)}min=this.gte;precision(e,r){return this._addCheck({kind:"precision",value:e,message:r})}wholeNumber(e,r){return this._addCheck({kind:"wholeNumber",value:e,message:r})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.value<e)&&(e=r.value);return e}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:e})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:e})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:e})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:e})}finite(e){return this._addCheck({kind:"finite",message:e})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:e})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:e})}get isFinite(){let e=null,r=null;for(let n of this._def.checks){if(n.kind==="finite")return!0;n.kind==="min"?(r===null||n.value>r)&&(r=n.value):n.kind==="max"&&(e===null||n.value<e)&&(e=n.value)}return Number.isFinite(r)&&Number.isFinite(e)}},me=le;Je(me,"create",e=>new le({checks:[],typeName:zr,coerce:e?.coerce??!1}));var gt=ft.object({template:ft.string().min(1,"Template cannot be empty")});var Wr=s.object({password:s.string(),registry:s.string().nullable(),username:s.string()}),Br=s.object({docker_compose_file:s.string(),docker_config:Wr.optional(),features:s.array(s.string()),kms_enabled:s.boolean(),manifest_version:s.number(),name:s.string(),public_logs:s.boolean(),public_sysinfo:s.boolean(),runner:s.string().optional(),salt:s.string().nullable().optional(),tproxy_enabled:s.boolean(),version:s.string().optional()}),Gr=s.object({name:s.string(),image:s.string(),compose_file:Br,vcpu:s.number(),memory:s.number(),disk_size:s.number(),ports:s.array(s.any())}),Hr=s.object({id:s.string(),name:s.string(),status:s.string(),uptime:s.string(),app_url:s.string(),app_id:s.string(),instance_id:s.string(),configuration:Gr,exited_at:s.string(),boot_progress:s.string(),boot_error:s.string(),shutdown_progress:s.string(),image_version:s.string()}),Kr=s.object({id:s.number(),username:s.string()}),qr=s.object({id:s.number(),name:s.string()}),Ne=s.object({hosted:Hr,name:s.string(),managed_user:Kr,node:qr,listed:s.boolean(),status:s.string(),in_progress:s.boolean(),dapp_dashboard_url:s.string().nullable(),syslog_endpoint:s.string(),allow_upgrade:s.boolean()}),ht=s.object({id:s.number(),name:s.string(),status:s.string(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),user_id:s.number(),app_id:s.string(),vm_uuid:s.string().nullable(),instance_id:s.string().nullable(),app_url:s.string().nullable(),base_image:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),manifest_version:s.number(),version:s.string(),runner:s.string(),docker_compose_file:s.string(),features:s.array(s.string()).nullable(),created_at:s.string(),encrypted_env_pubkey:s.string()}),yt=s.object({app_env_encrypt_pubkey:s.string(),app_id_salt:s.string()}),vt=s.object({id:s.number(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),name:s.string(),status:s.string(),in_progress:s.boolean(),app_id:s.string(),vm_uuid:s.string(),instance_id:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),base_image:s.string(),encrypted_env_pubkey:s.string(),listed:s.boolean(),project_id:s.string(),project_type:s.string().nullable()}),Ct=s.object({username:s.string(),email:s.string(),credits:me.create({coerce:!0}),role:s.string(),avatar:s.string(),flag_reset_password:s.boolean(),team_name:s.string(),team_tier:s.string(),trial_ended_at:s.string().nullable()}),In=s.array(Ne),bt=s.object({detail:s.string()}),Rn=s.object({key:s.string(),value:s.string()}),Oe=s.object({name:s.string(),description:s.string().optional(),version:s.array(s.number()).optional(),is_dev:s.boolean().optional(),rootfs_hash:s.string().optional(),shared_ro:s.boolean().optional(),cmdline:s.string().optional(),kernel:s.string().optional(),initrd:s.string().optional(),hda:s.string().nullable().optional(),rootfs:s.string().optional(),bios:s.string().optional()}),Zr=s.object({teepod_id:s.number(),name:s.string(),listed:s.boolean(),resource_score:s.number(),remaining_vcpu:s.number(),remaining_memory:s.number(),remaining_cvm_slots:s.number(),images:s.array(Oe).optional()}),Jr=s.object({max_instances:s.number().nullable(),max_vcpu:s.number().nullable(),max_memory:s.number().nullable(),max_disk:s.number().nullable()}),wt=s.object({tier:s.string(),capacity:Jr,nodes:s.array(Zr)});function kt(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function pe(){try{o.debug(`Fetching user info from ${x.USER_INFO}`);let t=await $.get(x.USER_INFO);o.debug(`Received response: ${kt(t)}`);try{return Ct.parse(t)}catch(e){throw o.error(`Failed to parse user info response: ${e}`),o.debug(`Response structure: ${kt(t)}`),e}}catch(t){throw o.error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`),new Error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`)}}var St=new Yr().name("login").description("Set the API key for authentication").argument("[api-key]","Phala Cloud API key to set").action(async t=>{try{let e;if(!t)t=(await Xr({type:"password",name:"apiKey",message:"Enter your API key:",validate:async n=>{if(n.length===0)return"API key cannot be empty";try{if(await nt(n),e=await pe(),!e.username)return await ie(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(e=await pe(),!e.username)return await ie(),"Invalid API key";o.success(`Welcome ${e.username}! API key validated and saved successfully
102
+ `;function Ie(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var Re=class{client;apiKey=null;constructor(e){o.debug(`Creating API client with base URL: ${e}`),this.client=Er.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${tt}`}}),this.client.interceptors.request.use(async r=>{if(!this.apiKey){if(this.apiKey=await Ce(),!this.apiKey)throw new Error('API key not found. Please set an API key first with "phala auth login"');o.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return r.headers["X-API-Key"]=this.apiKey,o.debug(`Making request to: ${r.baseURL}${r.url}`),r}),this.client.interceptors.response.use(r=>(o.debug(`Received successful response from: ${r.config.url}`),r),r=>{if(r.response){let{status:n,data:i}=r.response;o.debug(`Received error response: ${n} - ${Ie(i)}`),n===401?o.error("Authentication failed. Please check your API key."):n===403?o.error("You do not have permission to perform this action."):n===404?o.error("Resource not found."):o.error(`API Error (${n}): ${i.message||Ie(i)}`)}else r.request?(o.error("No response received from the server. Please check your internet connection."),o.debug(`Request details: ${Ie(r.request).substring(0,200)}...`)):o.error(`Error: ${r.message}`);return Promise.reject(r)})}async get(e,r){try{return o.debug(`GET request to: ${e}`),(await this.client.get(e,r)).data}catch(n){throw o.debug(`GET request failed: ${n instanceof Error?n.message:String(n)}`),n}}async post(e,r,n){try{return o.debug(`POST request to: ${e}`),(await this.client.post(e,r,n)).data}catch(i){throw o.debug(`POST request failed: ${i instanceof Error?i.message:String(i)}`),i}}async put(e,r,n){try{return o.debug(`PUT request to: ${e}`),(await this.client.put(e,r,n)).data}catch(i){throw o.debug(`PUT request failed: ${i instanceof Error?i.message:String(i)}`),i}}async delete(e,r){try{return o.debug(`DELETE request to: ${e}`),(await this.client.delete(e,r)).data}catch(n){throw o.debug(`DELETE request failed: ${n instanceof Error?n.message:String(n)}`),n}}async patch(e,r,n){try{return o.debug(`PATCH request to: ${e}`),(await this.client.patch(e,r,n)).data}catch(i){throw o.debug(`PATCH request failed: ${i instanceof Error?i.message:String(i)}`),i}}};o.debug(`Initializing API client with URL: ${Fe}`);var $=new Re(Fe);import{z as s}from"zod";import{INVALID as xr,ParseStatus as _r,ZodIssueCode as Y,ZodParsedType as ct,ZodType as $r,addIssueToContext as X,z as mt}from"zod";var Tr="ZodDecimal",Pr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,le=class extends $r{_parse(e){if(e.data!==null&&typeof e.data=="object"&&"toNumber"in e.data&&(e.data=e.data.toNumber()),this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==ct.number){let a=this._getOrReturnCtx(e);return X(a,{code:Y.invalid_type,expected:ct.number,received:a.parsedType}),xr}let n,i=new _r;for(let a of this._def.checks)if(a.kind==="precision"){let c=e.data.toString().match(Pr);Math.max((c[1]?c[1].length:0)-(c[2]?parseInt(c[2],10):0),0)>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.custom,message:a.message,params:{precision:a.value}}),i.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.custom,message:a.message,params:{wholeNumber:a.value}}),i.dirty()):a.kind==="min"?(a.inclusive?e.data<a.value:e.data<=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.too_small,minimum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="max"?(a.inclusive?e.data>a.value:e.data>=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:Y.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="finite"&&(Number.isFinite(e.data)||(n=this._getOrReturnCtx(e,n),X(n,{code:Y.not_finite,message:a.message}),i.dirty()));return{status:i.value,value:e.data}}setLimit(e,r,n,i){return new le({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:n,message:i}]})}_addCheck(e){return new le({...this._def,checks:[...this._def.checks,e]})}lte(e,r){return this.setLimit("max",e,!0,r)}lt(e,r){return this.setLimit("max",e,!1,r)}max=this.lte;gt(e,r){return this.setLimit("min",e,!1,r)}gte(e,r){return this.setLimit("min",e,!0,r)}min=this.gte;precision(e,r){return this._addCheck({kind:"precision",value:e,message:r})}wholeNumber(e,r){return this._addCheck({kind:"wholeNumber",value:e,message:r})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.value<e)&&(e=r.value);return e}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:e})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:e})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:e})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:e})}finite(e){return this._addCheck({kind:"finite",message:e})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:e})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:e})}get isFinite(){let e=null,r=null;for(let n of this._def.checks){if(n.kind==="finite")return!0;n.kind==="min"?(r===null||n.value>r)&&(r=n.value):n.kind==="max"&&(e===null||n.value<e)&&(e=n.value)}return Number.isFinite(r)&&Number.isFinite(e)}},me=le;Ge(me,"create",e=>new le({checks:[],typeName:Tr,coerce:e?.coerce??!1}));var lt=mt.object({template:mt.string().min(1,"Template cannot be empty")});var Dr=s.object({password:s.string(),registry:s.string().nullable(),username:s.string()}),Ar=s.object({docker_compose_file:s.string(),docker_config:Dr.optional(),features:s.array(s.string()),kms_enabled:s.boolean(),manifest_version:s.number(),name:s.string(),public_logs:s.boolean(),public_sysinfo:s.boolean(),runner:s.string().optional(),salt:s.string().nullable().optional(),tproxy_enabled:s.boolean(),version:s.string().optional()}),Fr=s.object({name:s.string(),image:s.string(),compose_file:Ar,vcpu:s.number(),memory:s.number(),disk_size:s.number(),ports:s.array(s.any())}),Ir=s.object({id:s.string(),name:s.string(),status:s.string(),uptime:s.string(),app_url:s.string(),app_id:s.string(),instance_id:s.string(),configuration:Fr,exited_at:s.string(),boot_progress:s.string(),boot_error:s.string(),shutdown_progress:s.string(),image_version:s.string()}),Rr=s.object({id:s.number(),username:s.string()}),Mr=s.object({id:s.number(),name:s.string()}),Me=s.object({hosted:Ir,name:s.string(),managed_user:Rr,node:Mr,listed:s.boolean(),status:s.string(),in_progress:s.boolean(),dapp_dashboard_url:s.string().nullable(),syslog_endpoint:s.string(),allow_upgrade:s.boolean()}),pt=s.object({id:s.number(),name:s.string(),status:s.string(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),user_id:s.number(),app_id:s.string(),vm_uuid:s.string().nullable(),instance_id:s.string().nullable(),app_url:s.string().nullable(),base_image:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),manifest_version:s.number(),version:s.string(),runner:s.string(),docker_compose_file:s.string(),features:s.array(s.string()).nullable(),created_at:s.string(),encrypted_env_pubkey:s.string()}),ut=s.object({app_env_encrypt_pubkey:s.string(),app_id_salt:s.string()}),dt=s.object({id:s.number(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),name:s.string(),status:s.string(),in_progress:s.boolean(),app_id:s.string(),vm_uuid:s.string(),instance_id:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),base_image:s.string(),encrypted_env_pubkey:s.string(),listed:s.boolean(),project_id:s.string(),project_type:s.string().nullable()}),ft=s.object({username:s.string(),email:s.string(),credits:me.create({coerce:!0}),role:s.string(),avatar:s.string(),flag_reset_password:s.boolean(),team_name:s.string(),team_tier:s.string(),trial_ended_at:s.string().nullable()}),dn=s.array(Me),gt=s.object({detail:s.string()}),fn=s.object({key:s.string(),value:s.string()}),Ve=s.object({name:s.string(),description:s.string().optional(),version:s.array(s.number()).optional(),is_dev:s.boolean().optional(),rootfs_hash:s.string().optional(),shared_ro:s.boolean().optional(),cmdline:s.string().optional(),kernel:s.string().optional(),initrd:s.string().optional(),hda:s.string().nullable().optional(),rootfs:s.string().optional(),bios:s.string().optional()}),Vr=s.object({teepod_id:s.number(),name:s.string(),listed:s.boolean(),resource_score:s.number(),remaining_vcpu:s.number(),remaining_memory:s.number(),remaining_cvm_slots:s.number(),images:s.array(Ve).optional()}),Lr=s.object({max_instances:s.number().nullable(),max_vcpu:s.number().nullable(),max_memory:s.number().nullable(),max_disk:s.number().nullable()}),ht=s.object({tier:s.string(),capacity:Lr,nodes:s.array(Vr)});function yt(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function pe(){try{o.debug(`Fetching user info from ${x.USER_INFO}`);let t=await $.get(x.USER_INFO);o.debug(`Received response: ${yt(t)}`);try{return ft.parse(t)}catch(e){throw o.error(`Failed to parse user info response: ${e}`),o.debug(`Response structure: ${yt(t)}`),e}}catch(t){throw o.error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`),new Error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`)}}var vt=new Nr().name("login").description("Set the API key for authentication").argument("[api-key]","Phala Cloud API key to set").action(async t=>{try{let e;if(!t)t=(await Or({type:"password",name:"apiKey",message:"Enter your API key:",validate:async n=>{if(n.length===0)return"API key cannot be empty";try{if(await Qe(n),e=await pe(),!e.username)return await ie(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(e=await pe(),!e.username)return await ie(),"Invalid API key";o.success(`Welcome ${e.username}! API key validated and saved successfully
103
103
  `),o.info(`
104
- Open in Web UI at https://phala.cloud/dashboard`)}catch(e){o.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Qr}from"commander";var Et=new Qr().name("logout").description("Remove the stored API key").action(async()=>{try{await ie(),o.success("API key removed successfully")}catch(t){o.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as eo}from"commander";var xt=new eo().name("status").description("Check authentication status").option("-j, --json","Output in JSON format").option("-d, --debug","Enable debug output").action(async t=>{try{t.debug&&(process.env.DEBUG="true");let e=await we();if(!e){o.warn('Not authenticated. Please set an API key with "phala auth login"');return}o.debug(`Using API key: ${e.substring(0,5)}...`);let r=o.startSpinner("Checking authentication status");try{let n=await pe();if(r.stop(!0),t.json){console.log(JSON.stringify(n,null,2));return}o.success(`Authenticated as ${n.username}`),o.break();let i={Username:n.username,Email:n.email,Role:n.role,Team:`${n.team_name} (${n.team_tier})`,Credits:`$${n.credits}`};n.trial_ended_at&&(i["Trial Ended At"]=n.trial_ended_at),console.table(i)}catch(n){r.stop(!1),o.error("Authentication failed. Your API key may be invalid or expired."),o.info('Please set a new API key with "phala auth login"'),t.debug&&o.debug(`Error details: ${n instanceof Error?n.message:String(n)}`)}}catch(e){o.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var _t=new to().name("auth").description("Authenticate with Phala Cloud").addCommand(St).addCommand(Et).addCommand(xt);import{Command as so}from"commander";import{Command as oo}from"commander";import{z as ro}from"zod";async function B(){try{let t=await $.get(x.TEEPODS);return wt.parse(t).nodes}catch(t){throw new Error(`Failed to get TEEPods: ${t instanceof Error?t.message:String(t)}`)}}async function ke(t){try{let r=(await B()).find(i=>i.teepod_id===Number(t));if(r&&r.images&&r.images.length>0)return r.images;let n=await $.get(x.TEEPOD_IMAGES(t));return ro.array(Oe).parse(n)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}var $t=new oo().name("list").alias("ls").description("List available TEEPods").action(async()=>{try{let t=o.startSpinner("Fetching TEEPods"),e=await B();if(t.stop(!0),e.length===0){o.info("No TEEPods found");return}o.info("Available TEEPods:"),o.table(e,["teepod_id","name"])}catch(t){o.error(`Failed to list TEEPods: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as no}from"commander";import io from"inquirer";var Tt=new no().name("images").description("List available images for a TEEPod").option("-t, --teepod-id <teepodId>","TEEPod ID").action(async t=>{try{let e=o.startSpinner(`Fetching images for TEEPod ${t.teepodId}`);if(!t.teepodId){let n=o.startSpinner("Fetching available TEEPods"),i=await B();n.stop(!0),i.length===0&&(o.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:a}=await io.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:i.map(c=>({name:`${c.name}`,value:c.teepod_id}))}]);t.teepodId=a}let r=await ke(t.teepodId);if(e.stop(!0),r.length===0){o.info(`No images found for TEEPod ${t.teepodId}`);return}o.info(`Available images for TEEPod ${t.teepodId}:`),o.table(r,["name","description"])}catch(e){o.error(`Failed to list images: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Pt=new so().name("teepods").description("TEEPod management commands").addCommand($t).addCommand(Tt);import{Command as Eo}from"commander";import{Command as vo}from"commander";import{execa as Rt}from"execa";import K from"fs";import Be from"path";import lo from"axios";import po from"handlebars";import{exec as uo,spawn as fo}from"child_process";import{promisify as go}from"util";import ho from"os";import ao from"inquirer";import Ue from"fs";import ze from"path";function R(t,e=process.cwd()){let r=ze.resolve(e,t);if(!Ue.existsSync(r))throw new Error(`File not found at ${r}`);return!0}async function G(t,e,r="file",n=process.cwd()){return(await ao.prompt([{type:"input",name:r,message:t,default:e,validate:a=>{let c=ze.resolve(n,a);return Ue.existsSync(c)?!0:`File not found at ${c}`}}]))[r]}function Se(t,e){for(let r of t){let n=ze.join(process.cwd(),r);if(Ue.existsSync(n))return e?o.info(e.replace("{path}",n)):o.info(`File detected: ${n}`),r}}import*as A from"fs";import*as z from"path";import*as Q from"os";import{execSync as ee,spawn as co}from"child_process";import*as je from"net";var D={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:z.join(Q.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:z.join(Q.homedir(),".phala-cloud","logs","tappd-simulator.log"),platforms:{darwin:{filename:"tappd-simulator-0.1.4-aarch64-apple-darwin.tgz",extractedFolder:"tappd-simulator-0.1.4-aarch64-apple-darwin",socketArg:"unix:/tmp/tappd.sock"},linux:{filename:"tappd-simulator-0.1.4-x86_64-linux-musl.tgz",extractedFolder:"tappd-simulator-0.1.4-x86_64-linux-musl",socketArg:"unix:/tmp/tappd.sock"},win32:{filename:"tappd-simulator-0.1.4-x86_64-pc-windows-msvc.tgz",extractedFolder:"tappd-simulator-0.1.4-x86_64-pc-windows-msvc",socketArg:"127.0.0.1:8090"}}};function Dt(){try{if(!A.existsSync(D.installDir))return!1;let t=Q.platform();if(!D.platforms[t])throw new Error(`Unsupported platform: ${t}`);let e=z.join(D.installDir,D.platforms[t].extractedFolder);if(!A.existsSync(e))return!1;let n=z.join(e,t==="win32"?"tappd-simulator.exe":"tappd-simulator");return A.existsSync(n)}catch(t){return o.error("Error checking if simulator is installed:",t),!1}}function ue(){let t=Q.platform();if(!D.platforms[t])throw new Error(`Unsupported platform: ${t}. Only darwin, linux, and win32 are supported.`);return t}async function Ft(t){let e=r=>{o.info(r),t&&t(r)};try{let r=ue(),n=D.platforms[r];A.existsSync(D.installDir)||(o.info(`Creating installation directory at ${D.installDir}`),A.mkdirSync(D.installDir,{recursive:!0})),process.chdir(D.installDir);let i=`${D.baseUrl}/${n.filename}`;o.info(`Downloading simulator from ${i}`),ee(`wget ${i}`,{stdio:"inherit"}),o.info(`Extracting ${n.filename}`),ee(`tar -xvf ${n.filename}`,{stdio:"inherit"}),o.success("Simulator installation completed successfully")}catch(r){throw o.error("Error installing simulator:",r),new Error(`Failed to install simulator: ${r}`)}}async function At(t={}){try{let e=ue(),r=D.platforms[e],n=z.join(D.installDir,r.extractedFolder);process.chdir(n);let i=e==="win32"?"tappd-simulator.exe":"./tappd-simulator",a={background:t.background??!0,logToFile:t.logToFile??!0,logFilePath:t.logFilePath??D.defaultLogPath};if(a.logToFile){let d=z.dirname(a.logFilePath);A.existsSync(d)||A.mkdirSync(d,{recursive:!0}),o.info(`Simulator logs will be written to: ${a.logFilePath}`)}o.info(`Starting simulator with: ${i} -l ${r.socketArg}`);let c="inherit",p=null;a.logToFile&&(p=A.createWriteStream(a.logFilePath,{flags:"a"}),c=["ignore",p,p]);let u=co(i,["-l",r.socketArg],{stdio:c,shell:e==="win32",detached:a.background});if(p){let d=new Date().toISOString();p.write(`
104
+ Open in Web UI at https://phala.cloud/dashboard`)}catch(e){o.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Ur}from"commander";var bt=new Ur().name("logout").description("Remove the stored API key").action(async()=>{try{await ie(),o.success("API key removed successfully")}catch(t){o.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as zr}from"commander";var Ct=new zr().name("status").description("Check authentication status").option("-j, --json","Output in JSON format").option("-d, --debug","Enable debug output").action(async t=>{try{t.debug&&(process.env.DEBUG="true");let e=await Ce();if(!e){o.warn('Not authenticated. Please set an API key with "phala auth login"');return}o.debug(`Using API key: ${e.substring(0,5)}...`);let r=o.startSpinner("Checking authentication status");try{let n=await pe();if(r.stop(!0),t.json){console.log(JSON.stringify(n,null,2));return}o.success(`Authenticated as ${n.username}`),o.break();let i={Username:n.username,Email:n.email,Role:n.role,Team:`${n.team_name} (${n.team_tier})`,Credits:`$${n.credits}`};n.trial_ended_at&&(i["Trial Ended At"]=n.trial_ended_at),console.table(i)}catch(n){r.stop(!1),o.error("Authentication failed. Your API key may be invalid or expired."),o.info('Please set a new API key with "phala auth login"'),t.debug&&o.debug(`Error details: ${n instanceof Error?n.message:String(n)}`)}}catch(e){o.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var wt=new jr().name("auth").description("Authenticate with Phala Cloud").addCommand(vt).addCommand(bt).addCommand(Ct);import{Command as Hr}from"commander";import{Command as Br}from"commander";import{z as Wr}from"zod";async function B(){try{let t=await $.get(x.TEEPODS);return ht.parse(t).nodes}catch(t){throw new Error(`Failed to get TEEPods: ${t instanceof Error?t.message:String(t)}`)}}async function we(t){try{let r=(await B()).find(i=>i.teepod_id===Number(t));if(r&&r.images&&r.images.length>0)return r.images;let n=await $.get(x.TEEPOD_IMAGES(t));return Wr.array(Ve).parse(n)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}var kt=new Br().name("list").alias("ls").description("List available TEEPods").action(async()=>{try{let t=o.startSpinner("Fetching TEEPods"),e=await B();if(t.stop(!0),e.length===0){o.info("No TEEPods found");return}o.info("Available TEEPods:"),o.table(e,["teepod_id","name"])}catch(t){o.error(`Failed to list TEEPods: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Gr}from"commander";import Kr from"inquirer";var St=new Gr().name("images").description("List available images for a TEEPod").option("-t, --teepod-id <teepodId>","TEEPod ID").action(async t=>{try{let e=o.startSpinner(`Fetching images for TEEPod ${t.teepodId}`);if(!t.teepodId){let n=o.startSpinner("Fetching available TEEPods"),i=await B();n.stop(!0),i.length===0&&(o.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:a}=await Kr.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:i.map(c=>({name:`${c.name}`,value:c.teepod_id}))}]);t.teepodId=a}let r=await we(t.teepodId);if(e.stop(!0),r.length===0){o.info(`No images found for TEEPod ${t.teepodId}`);return}o.info(`Available images for TEEPod ${t.teepodId}:`),o.table(r,["name","description"])}catch(e){o.error(`Failed to list images: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Et=new Hr().name("teepods").description("TEEPod management commands").addCommand(kt).addCommand(St);import{Command as lo}from"commander";import{Command as no}from"commander";import{execa as Pt}from"execa";import H from"fs";import ze from"path";import Yr from"axios";import Xr from"handlebars";import{exec as Qr,spawn as eo}from"child_process";import{promisify as to}from"util";import ro from"os";import qr from"inquirer";import Le from"fs";import Ne from"path";function R(t,e=process.cwd()){let r=Ne.resolve(e,t);if(!Le.existsSync(r))throw new Error(`File not found at ${r}`);return!0}async function G(t,e,r="file",n=process.cwd()){return(await qr.prompt([{type:"input",name:r,message:t,default:e,validate:a=>{let c=Ne.resolve(n,a);return Le.existsSync(c)?!0:`File not found at ${c}`}}]))[r]}function ke(t,e){for(let r of t){let n=Ne.join(process.cwd(),r);if(Le.existsSync(n))return e?o.info(e.replace("{path}",n)):o.info(`File detected: ${n}`),r}}import*as F from"fs";import*as z from"path";import*as Q from"os";import{execSync as ee,spawn as Zr}from"child_process";import*as Oe from"net";var A={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:z.join(Q.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:z.join(Q.homedir(),".phala-cloud","logs","tappd-simulator.log"),platforms:{darwin:{filename:"tappd-simulator-0.1.4-aarch64-apple-darwin.tgz",extractedFolder:"tappd-simulator-0.1.4-aarch64-apple-darwin",socketArg:"unix:/tmp/tappd.sock"},linux:{filename:"tappd-simulator-0.1.4-x86_64-linux-musl.tgz",extractedFolder:"tappd-simulator-0.1.4-x86_64-linux-musl",socketArg:"unix:/tmp/tappd.sock"},win32:{filename:"tappd-simulator-0.1.4-x86_64-pc-windows-msvc.tgz",extractedFolder:"tappd-simulator-0.1.4-x86_64-pc-windows-msvc",socketArg:"127.0.0.1:8090"}}};function xt(){try{if(!F.existsSync(A.installDir))return!1;let t=Q.platform();if(!A.platforms[t])throw new Error(`Unsupported platform: ${t}`);let e=z.join(A.installDir,A.platforms[t].extractedFolder);if(!F.existsSync(e))return!1;let n=z.join(e,t==="win32"?"tappd-simulator.exe":"tappd-simulator");return F.existsSync(n)}catch(t){return o.error("Error checking if simulator is installed:",t),!1}}function ue(){let t=Q.platform();if(!A.platforms[t])throw new Error(`Unsupported platform: ${t}. Only darwin, linux, and win32 are supported.`);return t}async function _t(t){let e=r=>{o.info(r),t&&t(r)};try{let r=ue(),n=A.platforms[r];F.existsSync(A.installDir)||(o.info(`Creating installation directory at ${A.installDir}`),F.mkdirSync(A.installDir,{recursive:!0})),process.chdir(A.installDir);let i=`${A.baseUrl}/${n.filename}`;o.info(`Downloading simulator from ${i}`),ee(`wget ${i}`,{stdio:"inherit"}),o.info(`Extracting ${n.filename}`),ee(`tar -xvf ${n.filename}`,{stdio:"inherit"}),o.success("Simulator installation completed successfully")}catch(r){throw o.error("Error installing simulator:",r),new Error(`Failed to install simulator: ${r}`)}}async function $t(t={}){try{let e=ue(),r=A.platforms[e],n=z.join(A.installDir,r.extractedFolder);process.chdir(n);let i=e==="win32"?"tappd-simulator.exe":"./tappd-simulator",a={background:t.background??!0,logToFile:t.logToFile??!0,logFilePath:t.logFilePath??A.defaultLogPath};if(a.logToFile){let d=z.dirname(a.logFilePath);F.existsSync(d)||F.mkdirSync(d,{recursive:!0}),o.info(`Simulator logs will be written to: ${a.logFilePath}`)}o.info(`Starting simulator with: ${i} -l ${r.socketArg}`);let c="inherit",p=null;a.logToFile&&(p=F.createWriteStream(a.logFilePath,{flags:"a"}),c=["ignore",p,p]);let u=Zr(i,["-l",r.socketArg],{stdio:c,shell:e==="win32",detached:a.background});if(p){let d=new Date().toISOString();p.write(`
105
105
  [${d}] Simulator started
106
- `)}return a.background&&(u.unref(),o.success("Simulator is running in the background")),await We(),u}catch(e){throw o.error("Error running simulator:",e),new Error(`Failed to run simulator: ${e}`)}}async function Ee(){try{let t=ue(),e=D.platforms[t];if(t==="darwin"||t==="linux"){let r="/tmp/tappd.sock";return A.existsSync(r)?new Promise(n=>{let i=je.createConnection({path:r}).on("connect",()=>{i.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{i.end(),n(!1)},1e3)}):!1}else if(t==="win32"){let r="127.0.0.1";return new Promise(i=>{let a=je.createConnection({host:r,port:8090}).on("connect",()=>{a.end(),i(!0)}).on("error",()=>{i(!1)});setTimeout(()=>{a.end(),i(!1)},1e3)})}return!1}catch(t){return o.error("Error checking if simulator is running:",t),!1}}async function It(){try{let t=ue();if(!await Ee())return o.info("Simulator is not running"),!0;o.info("Stopping simulator..."),t==="win32"?ee(`for /f "tokens=5" %a in ('netstat -ano ^| findstr :8080') do taskkill /F /PID %a`,{stdio:"inherit"}):ee("pkill -f tappd-simulator",{stdio:"inherit"});let e=!await Ee();return e?o.success("Simulator stopped successfully"):o.error("Failed to stop simulator"),await H(),e}catch(t){return o.error("Error stopping simulator:",t),!1}}function mo(){return ue()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function We(t){try{let e=mo(),r=t||e;return await ee(`export DSTACK_SIMULATOR_ENDPOINT=${r}`),o.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${r} for current process`),t}catch(e){throw o.error("Error setting simulator endpoint environment variable:",e),new Error(`Failed to set simulator endpoint: ${e}`)}}async function H(){return await ee("unset DSTACK_SIMULATOR_ENDPOINT"),o.success("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var de=go(uo),Mt=".phala-cloud/logs",yo=".phala-cloud/compose",Vt=10,_=class{username;image;registry;constructor(e,r,n){this.image=e,this.username=r||"",this.registry=n||""}ensureLogsDir(){let e=Be.resolve(Mt);K.existsSync(e)||K.mkdirSync(e,{recursive:!0})}getLogFilePath(e){let r=new Date().toISOString().replace(/[:.]/g,"-");return Be.resolve(Mt,`${this.image}-${e}-${r}.log`)}getSystemArchitecture(){let e=ho.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,r,n){return new Promise((i,a)=>{let c=fo(e,r),p=this.getLogFilePath(n);this.ensureLogsDir();let u=K.createWriteStream(p,{flags:"a"}),d=[],v=(y,m=!1)=>{let l=y.toString().split(`
107
- `);u.write(y),l.forEach(f=>{f.trim()&&(d.push(f),d.length>Vt&&d.shift(),console.clear(),console.log(`Latest ${Vt} lines (full log at ${p}):`),console.log("-".repeat(50)),d.forEach(h=>{m?console.error(h):console.log(h)}))})};c.stdout.on("data",y=>v(y)),c.stderr.on("data",y=>v(y,!0)),c.on("close",y=>{u.end(),y===0?(console.log(`
108
- Operation completed. Full log available at: ${p}`),i()):a(new Error(`Process exited with code ${y}. Check log file: ${p}`))}),c.on("error",y=>{u.end(),a(y)})})}setCredentials(e,r){this.username=e,r&&(this.registry=r)}async buildImage(e,r){try{let n=this.getSystemArchitecture(),i=`${this.username}/${this.image}:${r}`,a=o.startSpinner(`Building Docker image ${this.username}/${this.image}:${r}`);R(e);let c=["build","-t",i,"-f",e];return n==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),c.push("--platform","linux/amd64")),c.push("."),await this.spawnProcess("docker",c,"build"),a.stop(!0,`Docker image ${i} built successfully`),!0}catch(n){return o.error(`Failed to build Docker image: ${n instanceof Error?n.message:String(n)}`),!1}}async pushImage(e){try{let r=o.startSpinner(`Pushing Docker image ${this.username}/${this.image}:${e} to Docker Hub`);if(!await O())throw r.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let i=`${this.username}/${this.image}:${e}`;return console.log(`Pushing image ${i} to Docker Hub...`),await this.spawnProcess("docker",["push",i],"push"),r.stop(!0,`Docker image ${i} pushed successfully`),!0}catch(r){return o.error(`Failed to push Docker image: ${r instanceof Error?r.message:String(r)}`),!1}}async listTags(){try{let e=o.startSpinner(`Listing tags for ${this.username}/${this.image}`),r=await lo.get(`${at}/repositories/${this.username}/${this.image}/tags`);if(!r.data||!r.data.results)throw e.stop(!1),new Error("Failed to get tags from Docker Hub");let n=r.data.results.map(i=>i.name);return e.stop(!0,`Found ${n.length} tags`),n}catch(e){return o.error(`Failed to list tags: ${e instanceof Error?e.message:String(e)}`),[]}}async login(e,r,n){try{let i=o.startSpinner(`Logging in to Docker Hub as ${e}`);return await this.checkLogin()?(i.stop(!0,`Logged in as ${e}`),this.setCredentials(e,n),!0):(await Rt("docker",["login",...n?[n]:[],"-u",e,"--password-stdin"],{input:r}),i.stop(!0,"Logged in to Docker Hub successfully"),!0)}catch(i){return o.error(`Failed to login to Docker Hub: ${i instanceof Error?i.message:String(i)}`),!1}}async checkLogin(){try{let{stdout:e}=await Rt("docker",["login"]);return e.includes("Login Succeeded")}catch{return!1}}async buildComposeFile(e,r,n){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let i=n=="eliza"?pt:ut,a=gt.parse({template:i}),c=yo;K.existsSync(c)||(o.info(`Creating directory: ${c}`),K.mkdirSync(c,{recursive:!0}));let p=[];r&&(p=K.readFileSync(r,"utf-8").split(`
109
- `).filter(l=>l&&!l.startsWith("#")).map(l=>{let f=l.indexOf("#");return f>0&&(l=l.substring(0,f).trim()),l.trim()}).filter(l=>l.includes("=")).map(l=>{let[f,h]=l.split("=",2),C=f.trim();return(h?h.trim():"")===""?null:`${C}=${C}`}).filter(Boolean));let u=`${this.username}/${this.image}`,v=po.compile(a.template,{noEscape:!0})({imageName:u,tag:e,envVars:p.map(m=>m.replace(/=.*/,"=${"+m.split("=")[0]+"}"))}),y=Be.join(c,`${this.image}-${e}-tee-compose.yaml`);return K.writeFileSync(y,v),o.success(`Backup of docker compose file created at: ${y}`),y}async runComposeLocally(e,r){try{let n=o.startSpinner(`Running Docker Compose file at ${e}
106
+ `)}return a.background&&(u.unref(),o.success("Simulator is running in the background")),await Ue(),u}catch(e){throw o.error("Error running simulator:",e),new Error(`Failed to run simulator: ${e}`)}}async function Se(){try{let t=ue(),e=A.platforms[t];if(t==="darwin"||t==="linux"){let r="/tmp/tappd.sock";return F.existsSync(r)?new Promise(n=>{let i=Oe.createConnection({path:r}).on("connect",()=>{i.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{i.end(),n(!1)},1e3)}):!1}else if(t==="win32"){let r="127.0.0.1";return new Promise(i=>{let a=Oe.createConnection({host:r,port:8090}).on("connect",()=>{a.end(),i(!0)}).on("error",()=>{i(!1)});setTimeout(()=>{a.end(),i(!1)},1e3)})}return!1}catch(t){return o.error("Error checking if simulator is running:",t),!1}}async function Tt(){try{let t=ue();if(!await Se())return o.info("Simulator is not running"),!0;o.info("Stopping simulator..."),t==="win32"?ee(`for /f "tokens=5" %a in ('netstat -ano ^| findstr :8080') do taskkill /F /PID %a`,{stdio:"inherit"}):ee("pkill -f tappd-simulator",{stdio:"inherit"});let e=!await Se();return e?o.success("Simulator stopped successfully"):o.error("Failed to stop simulator"),await K(),e}catch(t){return o.error("Error stopping simulator:",t),!1}}function Jr(){return ue()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function Ue(t){try{let e=Jr(),r=t||e;return await ee(`export DSTACK_SIMULATOR_ENDPOINT=${r}`),o.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${r} for current process`),t}catch(e){throw o.error("Error setting simulator endpoint environment variable:",e),new Error(`Failed to set simulator endpoint: ${e}`)}}async function K(){return await ee("unset DSTACK_SIMULATOR_ENDPOINT"),o.success("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var de=to(Qr),Dt=".phala-cloud/logs",oo=".phala-cloud/compose",At=10,_=class{username;image;registry;constructor(e,r,n){this.image=e,this.username=r||"",this.registry=n||""}ensureLogsDir(){let e=ze.resolve(Dt);H.existsSync(e)||H.mkdirSync(e,{recursive:!0})}getLogFilePath(e){let r=new Date().toISOString().replace(/[:.]/g,"-");return ze.resolve(Dt,`${this.image}-${e}-${r}.log`)}getSystemArchitecture(){let e=ro.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,r,n){return new Promise((i,a)=>{let c=eo(e,r),p=this.getLogFilePath(n);this.ensureLogsDir();let u=H.createWriteStream(p,{flags:"a"}),d=[],v=(y,m=!1)=>{let l=y.toString().split(`
107
+ `);u.write(y),l.forEach(f=>{f.trim()&&(d.push(f),d.length>At&&d.shift(),console.clear(),console.log(`Latest ${At} lines (full log at ${p}):`),console.log("-".repeat(50)),d.forEach(h=>{m?console.error(h):console.log(h)}))})};c.stdout.on("data",y=>v(y)),c.stderr.on("data",y=>v(y,!0)),c.on("close",y=>{u.end(),y===0?(console.log(`
108
+ Operation completed. Full log available at: ${p}`),i()):a(new Error(`Process exited with code ${y}. Check log file: ${p}`))}),c.on("error",y=>{u.end(),a(y)})})}setCredentials(e,r){this.username=e,r&&(this.registry=r)}async buildImage(e,r){try{let n=this.getSystemArchitecture(),i=`${this.username}/${this.image}:${r}`,a=o.startSpinner(`Building Docker image ${this.username}/${this.image}:${r}`);R(e);let c=["build","-t",i,"-f",e];return n==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),c.push("--platform","linux/amd64")),c.push("."),await this.spawnProcess("docker",c,"build"),a.stop(!0,`Docker image ${i} built successfully`),!0}catch(n){return o.error(`Failed to build Docker image: ${n instanceof Error?n.message:String(n)}`),!1}}async pushImage(e){try{let r=o.startSpinner(`Pushing Docker image ${this.username}/${this.image}:${e} to Docker Hub`);if(!await O())throw r.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let i=`${this.username}/${this.image}:${e}`;return console.log(`Pushing image ${i} to Docker Hub...`),await this.spawnProcess("docker",["push",i],"push"),r.stop(!0,`Docker image ${i} pushed successfully`),!0}catch(r){return o.error(`Failed to push Docker image: ${r instanceof Error?r.message:String(r)}`),!1}}async listTags(){try{let e=o.startSpinner(`Listing tags for ${this.username}/${this.image}`),r=await Yr.get(`${rt}/repositories/${this.username}/${this.image}/tags`);if(!r.data||!r.data.results)throw e.stop(!1),new Error("Failed to get tags from Docker Hub");let n=r.data.results.map(i=>i.name);return e.stop(!0,`Found ${n.length} tags`),n}catch(e){return o.error(`Failed to list tags: ${e instanceof Error?e.message:String(e)}`),[]}}async login(e,r,n){try{let i=o.startSpinner(`Logging in to Docker Hub as ${e}`);return await this.checkLogin()?(i.stop(!0,`Logged in as ${e}`),this.setCredentials(e,n),!0):(await Pt("docker",["login",...n?[n]:[],"-u",e,"--password-stdin"],{input:r}),i.stop(!0,"Logged in to Docker Hub successfully"),!0)}catch(i){return o.error(`Failed to login to Docker Hub: ${i instanceof Error?i.message:String(i)}`),!1}}async checkLogin(){try{let{stdout:e}=await Pt("docker",["login"]);return e.includes("Login Succeeded")}catch{return!1}}async buildComposeFile(e,r,n){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let i=n=="eliza"?st:at,a=lt.parse({template:i}),c=oo;H.existsSync(c)||(o.info(`Creating directory: ${c}`),H.mkdirSync(c,{recursive:!0}));let p=[];r&&(p=H.readFileSync(r,"utf-8").split(`
109
+ `).filter(l=>l&&!l.startsWith("#")).map(l=>{let f=l.indexOf("#");return f>0&&(l=l.substring(0,f).trim()),l.trim()}).filter(l=>l.includes("=")).map(l=>{let[f,h]=l.split("=",2),b=f.trim();return(h?h.trim():"")===""?null:`${b}=${b}`}).filter(Boolean));let u=`${this.username}/${this.image}`,v=Xr.compile(a.template,{noEscape:!0})({imageName:u,tag:e,envVars:p.map(m=>m.replace(/=.*/,"=${"+m.split("=")[0]+"}"))}),y=ze.join(c,`${this.image}-${e}-tee-compose.yaml`);return H.writeFileSync(y,v),o.success(`Backup of docker compose file created at: ${y}`),y}async runComposeLocally(e,r){try{let n=o.startSpinner(`Running Docker Compose file at ${e}
110
110
  - If you run with the simulator, set DSTACK_SIMULATOR_ENDPOINT to http://host.docker.internal:8090`);R(e);let i=["-f",e,"up","-d"];return r&&(R(r),i.splice(2,0,"--env-file",r)),await de(`docker compose ${i.join(" ")}`),n.stop(!0,"Docker Compose file running successfully"),!0}catch(n){return o.error(`Failed to run Docker Compose file: ${n instanceof Error?n.message:String(n)}`),!1}}async runSimulator(e,r){try{o.info(`Running TEE simulator with image ${e}`),o.info("Pulling latest simulator image..."),await de(`docker pull ${e}`),o.info("Starting simulator in background...");let{stdout:n}=await de(`docker run -d --name tee-simulator --rm -p ${r}:${r} ${e}`),i=n.trim();return o.success(`TEE simulator running successfully. Container ID: ${i}`),o.info(`
111
111
 
112
112
  Useful commands:`),o.info(`- View logs: docker logs -f ${i}`),o.info(`- Stop simulator: docker stop ${i}
113
- `),We(`http://localhost:${r}`),!0}catch(n){return o.error(`Failed to run TEE simulator: ${n instanceof Error?n.message:String(n)}`),!1}}async stopSimulator(){try{let e=o.startSpinner("Stopping TEE simulator...");return await de("docker stop tee-simulator"),await H(),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return o.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),!1}}static async listLocalImages(){try{let{stdout:e}=await de('docker images --format "{{.Repository}}:{{.Tag}}"'),n=(await O())?.username;return e.split(`
114
- `).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${n}/`)).map(a=>{let[c,p]=a.split(":"),u=c.split("/");return{name:u.length>1?u[1]:c,tag:p}})}catch(e){return o.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import Lt from"prompts";var Nt=new vo().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 t=>{try{let e=t.username,r=t.password,n=t.registry;if(!e){o.info("First we need your Docker Hub username to check if you are already logged in.");let p=await Lt({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:u=>u.length>0?!0:"Username cannot be empty"});p.username||(o.error("Username is required"),process.exit(1)),e=p.username}let i=new _("",e,n);if(await i.login(e)){o.success(`${e} is logged in to Docker Hub`);return}if(!r){let p=await Lt({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:u=>u.length>0?!0:"Password cannot be empty"});p.password||(o.error("Password is required"),process.exit(1)),r=p.password}await i.login(e,r,n)||(o.error("Failed to login to Docker Hub"),process.exit(1)),await it({username:e,registry:n||null}),o.success("Logged in to Docker Hub successfully")}catch(e){o.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Co}from"commander";import Ot from"path";import Ut from"inquirer";import bo from"fs";var zt=new Co().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 t=>{try{let e=await O();if(e||(o.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!t.image){let c=await Ut.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:p=>p.trim()?!0:"Image name is required"}]);t.image=c.image}if(!t.tag){let c=await Ut.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:p=>p.trim()?!0:"Tag is required"}]);t.tag=c.tag}let r=Ot.resolve(process.cwd(),t.file);bo.existsSync(r)||(o.info(`Default Dockerfile not found at ${r}`),t.file=await G("Enter the path to your Dockerfile:","Dockerfile","file"));let n=Ot.resolve(process.cwd(),t.file);await new _(t.image,e.username,e.registry).buildImage(n,t.tag)||(o.error("Failed to build Docker image"),process.exit(1)),o.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){o.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as wo}from"commander";import jt from"inquirer";var Wt=new wo().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").action(async t=>{try{let e=await O();e||(o.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let r=t.image,n=t.tag;if(!r||!n){let c=await _.listLocalImages();if(c.length===0&&(o.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let p=Array.from(new Set(c.map(d=>d.name))),{selectedImage:u}=await jt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:p}]);r=u}if(!n){let p=c.filter(d=>d.name===r).map(d=>d.tag);p.length===0&&(o.error(`No tags found for image ${r}`),process.exit(1));let{selectedTag:u}=await jt.prompt([{type:"list",name:"selectedTag",message:`Select a tag for ${r}:`,choices:p}]);n=u}}await new _(r,e.username,e.registry).pushImage(n)||(o.error("Failed to push Docker image"),process.exit(1)),o.success(`Docker image ${e.username}/${r}:${n} pushed successfully`)}catch(e){o.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ko}from"commander";import xe from"inquirer";import Bt from"fs";import Gt from"path";var Ht=new ko().name("run").description("Run a Docker Compose setup").option("-c, --compose <compose>","Path to docker-compose.yml file").option("-e, --env-file <env-file>","Path to environment variables file").option("--skip-env","Skip environment variables file prompt",!0).action(async t=>{try{let e=t.compose,r=t.env;if(e)try{R(e)}catch{o.error(`File not found: ${e}`),process.exit(1)}else{let a=Gt.join(process.cwd(),"docker-compose.yml");if(Bt.existsSync(a)){let{useDefault:p}=await xe.prompt([{type:"confirm",name:"useDefault",message:"Use docker-compose.yml in current directory?",default:!0}]);p&&(e=a)}if(!e){let{composePath:p}=await xe.prompt([{type:"input",name:"composePath",message:"Enter path to docker-compose.yml file:",validate:u=>R(u)?!0:"File not found"}]);e=p}}if(!r&&!t.skipEnv){let a=Gt.join(process.cwd(),".env");if(Bt.existsSync(a)){let{useDefault:p}=await xe.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);p&&(r=a)}if(!r){let{envPath:p}=await xe.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:u=>{try{return R(u),!0}catch{return`File not found: ${u}`}}}]);r=p}}let n=new _("");if(r){try{R(r)}catch{o.error(`File not found: ${r}`),process.exit(1)}o.info(`Running Docker Compose with compose file: ${e} and env file: ${r}`)}else o.info(`Running Docker Compose with compose file: ${e} without env file`);await n.runComposeLocally(e,r)||(o.error("Failed to run Docker Compose"),process.exit(1)),o.success("Docker Compose is running")}catch(e){o.error(`Failed to run Docker Compose: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as So}from"commander";import M from"inquirer";import fe from"fs";import _e from"path";var Kt=new So().name("generate").description("Generate a Docker Compose file").option("-i, --image <image>","Docker image name to use in the compose file").option("-t, --tag <tag>","Docker image tag to use in the compose file").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").option("--manual","Skip automatic image detection and enter image/tag manually").action(async t=>{try{let e=await O();(!e||!e.username)&&(o.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let r=t.image||"",n=t.tag||"";if((!r||!n)&&!t.manual)try{o.info("Detecting local Docker images...");let u=await _.listLocalImages();if(u.length===0)o.warn("No local Docker images found. You will need to enter image details manually.");else{let d=new Map;if(u.forEach(v=>{d.has(v.name)||d.set(v.name,[]),d.get(v.name)?.push(v.tag)}),r&&!n){let v=d.get(r)||[];if(v.length>0){let{imageTag:y}=await M.prompt([{type:"list",name:"imageTag",message:`Select a tag for ${r}:`,choices:[...v,new M.Separator,"[ Enter manually ]"]}]);y!=="[ Enter manually ]"&&(n=y)}else o.warn(`No tags found for image ${r}. You will need to enter the tag manually.`)}else if(!r){let v=Array.from(d.keys()),{imageName:y}=await M.prompt([{type:"list",name:"imageName",message:"Select a Docker image:",choices:[...v,new M.Separator,"[ Enter manually ]"]}]);if(y!=="[ Enter manually ]"){r=y;let m=d.get(y)||[],{imageTag:l}=await M.prompt([{type:"list",name:"imageTag",message:"Select a tag:",choices:[...m,new M.Separator,"[ Enter manually ]"]}]);l!=="[ Enter manually ]"&&(n=l)}}}}catch(u){o.warn(`Failed to detect local images: ${u instanceof Error?u.message:String(u)}`),o.info("Continuing with manual input...")}if(!r){let{inputImage:u}=await M.prompt([{type:"input",name:"inputImage",message:"Enter Docker image name:",validate:d=>d.trim()?!0:"Image name cannot be empty"}]);r=u}if(!n){let{inputTag:u}=await M.prompt([{type:"input",name:"inputTag",message:`Enter tag for image ${r}:`,validate:d=>d.trim()?!0:"Tag cannot be empty"}]);n=u}let i=t.envFile;if(i)try{R(i)}catch{o.error(`File not found: ${i}`),process.exit(1)}else{let u=_e.join(process.cwd(),".env");if(fe.existsSync(u)){let{useDefault:v}=await M.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);v&&(i=u)}if(!i){let{envPath:v}=await M.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:y=>{try{return R(y),!0}catch{return`File not found: ${y}`}}}]);i=v}}let a=t.output;if(!a&&(a=_e.join(process.cwd(),"docker-compose.yml"),fe.existsSync(a))){let{confirmOverwrite:u}=await M.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${a} already exists. Overwrite?`,default:!1}]);if(!u){let{customPath:d}=await M.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:_e.join(process.cwd(),"docker-generated-compose.yml")}]);a=d}}let c=new _(r,e.username,e.registry);i?o.info(`Generating Docker Compose file for ${r}:${n} using env file: ${i}`):o.info(`Generating Docker Compose file for ${r}:${n} without env file`);let p=await c.buildComposeFile(n,i,t.template);if(p!==a){let u=_e.dirname(a);fe.existsSync(u)||(o.info(`Creating directory: ${u}`),fe.mkdirSync(u,{recursive:!0})),fe.copyFileSync(p,a)}o.success(`Docker Compose file generated successfully: ${a}`)}catch(e){o.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var qt=new Eo().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(Nt).addCommand(zt).addCommand(Ht).addCommand(Wt).addCommand(Kt);import{Command as $o}from"commander";import{Command as xo}from"commander";var Zt=new xo().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",ct).option("-p, --port <port>","Simulator port (default: 8090)","8090").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async t=>{try{if(t.type==="docker")await new _("").runSimulator(t.image,t.port)||(o.error("Failed to start TEE simulator"),process.exit(1));else if(t.type==="native")if(Dt()||await Ft(),await Ee()){o.success("TEE simulator is already running");return}else{let r=At();o.success("TEE simulator started successfully")}else o.error("Invalid simulator type"),process.exit(1)}catch(e){o.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as _o}from"commander";var Jt=new _o().name("stop").description("Stop the TEE simulator").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async t=>{try{t.type==="docker"?await new _("").stopSimulator()||(o.error("Failed to stop TEE simulator"),process.exit(1)):t.type==="native"?await It()||(o.error("Failed to stop TEE simulator"),process.exit(1)):(o.error("Invalid simulator type"),process.exit(1))}catch(e){o.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Yt=new $o().name("simulator").description("TEE simulator commands").addCommand(Zt).addCommand(Jt);import{Command as Ro}from"commander";import{Command as Fo}from"commander";import ge from"fs";import Xt from"path";import To from"os";var $e=Xt.join(To.homedir(),".phala-cloud"),He=Xt.join($e,"config.json"),Ge={apiUrl:"https://cloud-api.phala.network",cloudUrl:"https://cloud.phala.network",defaultTeepodId:3,defaultImage:"dstack-dev-0.3.5",defaultVcpu:1,defaultMemory:2048,defaultDiskSize:20};function Po(){if(!ge.existsSync($e))try{ge.mkdirSync($e,{recursive:!0})}catch(t){throw o.error(`Failed to create directory ${$e}:`,t),t}}function Te(){try{if(ge.existsSync(He)){let t=ge.readFileSync(He,"utf8");return{...Ge,...JSON.parse(t)}}return Ge}catch(t){return o.error("Failed to load configuration:",t),Ge}}function Do(t){Po();try{ge.writeFileSync(He,JSON.stringify({...Te(),...t},null,2),{mode:384}),o.success("Configuration saved successfully.")}catch(e){throw o.error("Failed to save configuration:",e),e}}function Qt(t){return Te()[t]}function er(t,e){let r=Te();r[t]=e,Do(r)}function tr(){return Te()}var rr=new Fo().name("get").description("Get a configuration value").argument("<key>","Configuration key").action(t=>{try{let e=Qt(t);e===void 0&&(o.error(`Configuration key '${t}' not found`),process.exit(1)),o.info(`${t}: ${JSON.stringify(e)}`)}catch(e){o.error(`Failed to get configuration value: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Ao}from"commander";var or=new Ao().name("set").description("Set a configuration value").argument("<key>","Configuration key").argument("<value>","Configuration value").action((t,e)=>{try{let r=e;if(e.startsWith("{")||e.startsWith("[")||e==="true"||e==="false"||!isNaN(Number(e)))try{r=JSON.parse(e)}catch{}er(t,r),o.success(`Configuration value for '${t}' set successfully`)}catch(r){o.error(`Failed to set configuration value: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Io}from"commander";var nr=new Io().name("list").alias("ls").description("List all configuration values").option("-j, --json","Output in JSON format").action(t=>{try{let e=tr();if(t.json){console.log(JSON.stringify(e,null,2));return}o.info("Configuration values:");for(let[r,n]of Object.entries(e))o.info(`${r}: ${JSON.stringify(n)}`)}catch(e){o.error(`Failed to list configuration values: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var ir=new Ro().name("config").description("Manage your local configuration").addCommand(rr).addCommand(or).addCommand(nr);import{Command as Xo}from"commander";import{Command as Vo}from"commander";import Mo from"inquirer";import{z as sr}from"zod";async function Pe(){try{let t=await $.get(x.CVMS(0));return sr.array(Ne).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function F(t){let r=(await Pe()).find(n=>n.hosted?.app_id===t||`app_${n.hosted?.app_id}`===t);if(!r)o.error(`CVM with App ID ${t} not detected`),process.exit(1);else return o.success(`CVM with App ID ${t} detected`),r.hosted?.app_id}async function te(t){try{let e=await $.get(x.CVM_BY_APP_ID(t));return vt.parse(e)}catch(e){throw new Error(`Failed to get CVM by App ID: ${e instanceof Error?e.message:String(e)}`)}}async function ar(t){try{let e=await $.post(x.CVM_PUBKEY,t);return yt.parse(e)}catch(e){throw new Error(`Failed to get pubkey from CVM: ${e instanceof Error?e.message:String(e)}`)}}async function cr(t){try{let e=await $.post(x.CVM_FROM_CONFIGURATION,t);return ht.parse(e)}catch(e){throw e instanceof sr.ZodError?(o.error("Schema validation error:",JSON.stringify(e.errors,null,2)),o.error("API response:",JSON.stringify(e.format(),null,2)),new Error(`Response validation failed: ${JSON.stringify(e.errors)}`)):new Error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`)}}async function mr(t){try{return await $.post(x.CVM_START(t)),!0}catch(e){throw new Error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`)}}async function lr(t){try{return await $.post(x.CVM_STOP(t)),!0}catch(e){throw new Error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`)}}async function pr(t){try{return await $.post(x.CVM_RESTART(t)),!0}catch(e){throw new Error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`)}}async function ur(t,e){try{let r=await $.put(x.CVM_UPGRADE(t),e);return bt.parse(r)}catch(r){throw new Error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`)}}async function dr(t){try{return await $.delete(x.CVM_BY_APP_ID(t)),!0}catch(e){throw new Error(`Failed to delete CVM: ${e instanceof Error?e.message:String(e)}`)}}async function T(){let t=o.startSpinner("Fetching available CVMs"),e=await Pe();if(t.stop(!0),!e||e.length===0){o.info("No CVMs found for your account");return}let r=e.map(i=>{let a=i.hosted?.app_id||i.hosted?.id,c=i.name||i.hosted&&i.hosted.name,p=i.status||i.hosted&&i.hosted.status;return{name:`${c||"Unnamed"} (${a}) - Status: ${p||"Unknown"}`,value:a}}),{selectedCvm:n}=await Mo.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:r}]);return n}async function fr(t){try{return await $.get(x.CVM_ATTESTATION(t))}catch(e){throw new Error(`Failed to get attestation information: ${e instanceof Error?e.message:String(e)}`)}}async function gr(t,e,r,n,i){try{let a={};if(e!==void 0&&(a.vcpu=e),r!==void 0&&(a.memory=r),n!==void 0&&(a.disk_size=n),i!==void 0&&(a.allow_restart=i),Object.keys(a).length===0)throw new Error("At least one resource parameter must be provided");return await $.patch(x.CVM_RESIZE(t),a),!0}catch(a){throw new Error(`Failed to resize CVM: ${a instanceof Error?a.message:String(a)}`)}}import Ke from"chalk";var hr=new Vo().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=o.startSpinner("Fetching CVMs"),r=await Pe();if(e.stop(!0),!r||r.length===0){o.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(r,null,2));return}r.forEach(n=>{o.keyValueTable({"App ID":`app_${n.hosted.app_id}`,Name:n.name,Status:n.status==="running"?Ke.green(n.status):n.status==="stopped"?Ke.red(n.status):Ke.yellow(n.status),"Node Info URL":n.hosted.app_url,"App URL":`${J}/dashboard/cvms/app_${n.hosted.app_id}`})}),o.success(`Found ${r.length} CVMs:`)}catch(e){o.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Lo}from"commander";import qe from"chalk";var yr=new Lo().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(t,e)=>{try{if(t)t=await F(t);else if(t=await T(),!t){o.info("No CVMs found or selection cancelled");return}let r=o.startSpinner(`Fetching CVM with App ID ${t}`),n=await te(t);if(r.stop(!0),n||(o.error(`CVM with App ID ${t} not found`),process.exit(1)),e.json){console.log(JSON.stringify(n,null,2));return}o.keyValueTable({Name:n.name,"App ID":`app_${n.app_id}`,Status:n.status==="running"?qe.green(n.status):n.status==="stopped"?qe.red(n.status):qe.yellow(n.status),vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"TEEPod ID":n.teepod_id,"App URL":`${J}/dashboard/cvms/app_${n.app_id}`})}catch(r){o.error(`Failed to get CVM details: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as No}from"commander";var vr=new No().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 t=>{try{if(t)t=await F(t);else if(t=await T(),!t)return;let e=o.startSpinner(`Starting CVM with App ID ${t}`);await mr(t),e.stop(!0),o.success(`CVM with App ID ${t} started successfully`)}catch(e){o.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Oo}from"commander";var Cr=new Oo().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 t=>{try{if(t)t=await F(t);else if(t=await T(),!t)return;let e=o.startSpinner(`Stopping CVM with App ID ${t}`);await lr(t),e.stop(!0),o.success(`CVM with App ID ${t} stopped successfully`)}catch(e){o.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Uo}from"commander";var br=new Uo().name("restart").description("Restart a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async t=>{try{if(t)t=await F(t);else if(t=await T(),!t)return;let e=o.startSpinner(`Restarting CVM with App ID ${t}`);await pr(t),e.stop(!0),o.success(`CVM with App ID ${t} restarted successfully`)}catch(e){o.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as zo}from"commander";import De from"chalk";var wr=new zo().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(t,e)=>{try{if(t)t=await F(t);else{o.info("No CVM specified, fetching available CVMs...");let n=await T();if(!n)return;t=n}o.info(`Fetching attestation information for CVM ${t}...`);let r=o.startSpinner("Fetching attestation information");try{let n=await fr(t);if(r.stop(!0),!n||Object.keys(n).length===0){o.info("No attestation information found");return}if(e?.json){o.info(JSON.stringify(n,null,2));return}o.success("Attestation Summary:");let i={Status:n.is_online?De.green("Online"):De.red("Offline"),"Public Access":n.is_public?De.green("Enabled"):De.yellow("Disabled"),Error:n.error||"None",Certificates:`${n.app_certificates?.length||0} found`};o.keyValueTable(i,{borderStyle:"rounded"}),n.app_certificates&&n.app_certificates.length>0&&n.app_certificates.forEach((a,c)=>{o.success(`Certificate #${c+1} (${a.position_in_chain===0?"End Entity":"CA"}):`);let p={Subject:`${a.subject.common_name||"Unknown"}${a.subject.organization?` (${a.subject.organization})`:""}`,Issuer:`${a.issuer.common_name||"Unknown"}${a.issuer.organization?` (${a.issuer.organization})`:""}`,"Serial Number":a.serial_number,Validity:`${new Date(a.not_before).toLocaleString()} to ${new Date(a.not_after).toLocaleString()}`,Fingerprint:a.fingerprint,"Signature Algorithm":a.signature_algorithm,"Is CA":a.is_ca?"Yes":"No","Position in Chain":a.position_in_chain};o.keyValueTable(p,{borderStyle:"single"})}),n.tcb_info&&(o.success("Trusted Computing Base (TCB) Information:"),o.keyValueTable(n.tcb_info,{borderStyle:"single"}))}catch(n){throw r.stop(!0),n}}catch(r){o.error(`Failed to get attestation information: ${r instanceof Error?r.message:String(r)}`)}});import{Command as Wo}from"commander";import{encryptEnvVars as Bo}from"@phala/dstack-sdk/encrypt-env-vars";import kr from"fs";import Go from"path";import ye from"inquirer";import jo from"fs";var he=(t,e)=>{let r={};if(t){for(let n of t)if(n.includes("=")){let[i,a]=n.split("=");i&&a&&(r[i]=a)}}if(e){let n=jo.readFileSync(e,"utf8");for(let i of n.split(`
115
- `))if(!(!i.trim()||i.trim().startsWith("#"))&&i.includes("=")){let[a,...c]=i.split("="),p=c.join("="),u=p.search(/\s+#/);u!==-1&&(p=p.substring(0,u).trim()),a&&p&&(r[a.trim()]=p.trim())}}return Object.entries(r).map(([n,i])=>({key:n,value:i}))};var Sr=new Wo().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",String(se)).option("--memory <memory>","Memory in MB",String(ae)).option("--disk-size <diskSize>","Disk size in GB",String(ce)).option("--teepod-id <teepodId>","TEEPod ID to use",mt).option("--image <image>","Version of dstack image to use",lt).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 t=>{try{if(!t.name){let{name:m}=await ye.prompt([{type:"input",name:"name",message:"Enter a name for the CVM:",validate:l=>l.trim()?!0:"CVM name is required"}]);t.name=m}if(!t.compose){let l=Se(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");t.compose=await G("Enter the path to your Docker Compose file:",l,"file")}let e=Go.resolve(t.compose);kr.existsSync(e)||(o.error(`Docker Compose file not found: ${e}`),process.exit(1));let r=kr.readFileSync(e,"utf8");await H();let n=[];if(t.envFile)try{n=he([],t.envFile)}catch(m){o.error(`Failed to read environment file: ${m instanceof Error?m.message:String(m)}`),process.exit(1)}else if(!t.skipEnv)if(await ye.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!1}]))o.info("Skipping environment variable prompt");else{let l=await G("Enter the path to your environment file:",".env","file");n=he([],l)}let i=[];if(t.vcpu===String(se)&&i.push({type:"input",name:"vcpu",message:`Enter number of vCPUs (default: ${se}):`,default:String(se),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.memory===String(ae)&&i.push({type:"input",name:"memory",message:`Enter memory in MB (default: ${ae}):`,default:String(ae),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.diskSize===String(ce)&&i.push({type:"input",name:"diskSize",message:`Enter disk size in GB (default: ${ce}):`,default:String(ce),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),i.length>0){let m=await ye.prompt(i);m.vcpu&&(t.vcpu=m.vcpu),m.memory&&(t.memory=m.memory),m.diskSize&&(t.diskSize=m.diskSize)}if(!t.teepodId){let m=o.startSpinner("Fetching available TEEPods"),l=await B();m.stop(!0),l.length===0&&(o.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:f}=await ye.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:l.map(C=>({name:`${C.name}`,value:C.teepod_id}))}]),h=l.find(C=>C.teepod_id===f);h||(o.error("Failed to find selected TEEPod"),process.exit(1)),o.info(`Selected TEEPod: ${h.name}`),t.teepodId=h.teepod_id}if(!t.image){let l=(await ke(t.teepodId)).map(h=>({name:`${h.name}`,value:h.name})),{selectedImage:f}=await ye.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:l}]);t.image=f.value}let a={teepod_id:t.teepodId||3,name:t.name,image:t.image||"dstack-dev-0.3.5",vcpu:parseInt(t.vcpu),memory:parseInt(t.memory),disk_size:parseInt(t.diskSize),compose_manifest:{docker_compose_file:r,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:t.name,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},c=o.startSpinner("Getting public key from CVM"),p=await ar(a);c.stop(!0),p||(o.error("Failed to get public key from CVM"),process.exit(1));let u=o.startSpinner("Encrypting environment variables"),d=await Bo(n,p.app_env_encrypt_pubkey);u.stop(!0),t.debug&&(o.debug("Public key:",p.app_env_encrypt_pubkey),o.debug("Encrypted environment variables:",d),o.debug("Environment variables:",JSON.stringify(n)));let v=o.startSpinner("Creating CVM"),y=await cr({...a,encrypted_env:d,app_env_encrypt_pubkey:p.app_env_encrypt_pubkey,app_id_salt:p.app_id_salt});v.stop(!0),y||(o.error("Failed to create CVM"),process.exit(1)),o.success("CVM created successfully"),o.info(`CVM ID: ${y.id}`),o.info(`Name: ${y.name}`),o.info(`Status: ${y.status}`),o.info(`App ID: ${y.app_id}`),y.app_url?o.info(`App URL: ${y.app_url}`):o.info(`App URL: ${J}/dashboard/cvms/app_${y.app_id}`),o.info(""),o.info("Your CVM is being created. You can check its status with:"),o.info(`phala cvms get ${y.app_id}`)}catch(e){o.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Ho}from"commander";import Ko from"inquirer";var Er=new Ho().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(t,e)=>{try{if(t)t=await checkCvmExists(t);else if(t=await T(),!t)return;if(!e.force){let{confirm:i}=await Ko.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID ${t}? This action cannot be undone.`,default:!1}]);if(!i){o.info("Deletion cancelled");return}}let r=o.startSpinner(`Deleting CVM ${t}`),n=await dr(t);r.stop(!0),n||(o.error(`Failed to delete CVM ${t}`),process.exit(1)),o.success(`CVM ${t} deleted successfully`)}catch(r){o.error(`Failed to delete CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as qo}from"commander";import Zo from"fs";import{encryptEnvVars as Jo}from"@phala/dstack-sdk/encrypt-env-vars";var xr=new qo().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(t,e)=>{try{if(t)t=await F(t);else{o.info("No CVM specified, fetching available CVMs...");let d=await T();if(!d)return;t=d}let r=o.startSpinner(`Fetching current configuration for CVM ${t}`),n=await te(t);if(r.stop(!0),n||(o.error(`CVM with App ID ${t} not found`),process.exit(1)),!e.compose){let v=Se(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");e.compose=await G("Enter the path to your Docker Compose file:",v,"file")}let i="";if(e.compose)try{i=Zo.readFileSync(e.compose,"utf8")}catch(d){o.error(`Failed to read Docker Compose file: ${d instanceof Error?d.message:String(d)}`),process.exit(1)}await H();let a="";if(e.envFile){let d=[];if(e.envFile)try{d=he([],e.envFile),a=await Jo(d,n.encrypted_env_pubkey)}catch(v){o.error(`Failed to read environment file: ${v instanceof Error?v.message:String(v)}`),process.exit(1)}}let c={compose_manifest:{docker_compose_file:i,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${e.appId}`},encrypted_env:a,allow_restart:!0},p=o.startSpinner(`Upgrading CVM ${t}`),u=await ur(t,c);p.stop(!0),u||(o.error("Failed to upgrade CVM"),process.exit(1)),o.success(`CVM ${t} upgraded successfully`),u.detail&&o.info(`Details: ${u.detail}`)}catch(r){o.error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Yo}from"commander";import ve from"inquirer";import j from"chalk";var _r=new Yo().name("resize").description("Resize resources for a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").option("-v, --vcpu <vcpu>","Number of virtual CPUs").option("-m, --memory <memory>","Memory size in MB").option("-d, --disk-size <diskSize>","Disk size in GB").option("-r, --allow-restart <allowRestart>","Allow restart of the CVM if needed for resizing").option("-y, --yes","Automatically confirm the resize operation").action(async(t,e)=>{try{if(t)t=await F(t);else if(t=await T(),!t){o.info("No CVMs found or selection cancelled");return}let r=await te(t),n=e.vcpu,i=e.memory,a=e.diskSize,c=e.allowRestart;n||(n=(await ve.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.vcpu,filter:y=>parseInt(y)}])).vcpu),i||(i=(await ve.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.memory,filter:y=>parseInt(y)}])).memory),a||(a=(await ve.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.disk_size,filter:y=>parseInt(y)}])).diskSize),c||(c=(await ve.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let p=`Are you sure you want to resize CVM ${t} with the following changes:
116
- `;if(o.keyValueTable({vCPUs:r.vcpu!==n?`${j.red(r.vcpu)} -> ${j.green(n)}`:r.vcpu,Memory:r.memory!==i?`${j.red(r.memory)} MB -> ${j.green(i)} MB`:r.memory,"Disk Size":r.disk_size!==a?`${j.red(r.disk_size)} GB -> ${j.green(a)} GB`:r.disk_size,"Allow Restart":c?j.green("Yes"):j.red("No")}),!e.yes){let{confirm:v}=await ve.prompt([{type:"confirm",name:"confirm",message:p,default:!1}]);if(!v){o.info("Resize operation cancelled");return}}let u=o.startSpinner(`Resizing CVM with App ID ${t}`);await gr(t,n,i,a,c?1:0),u.stop(!0),o.success(`CVM with App ID ${t} resized successfully`)}catch(r){o.error(`Failed to resize CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var $r=new Xo().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(hr).addCommand(yr).addCommand(Sr).addCommand(xr).addCommand(vr).addCommand(Cr).addCommand(br).addCommand(wr).addCommand(Er).addCommand(_r);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function en(){new Qo().name("phala").description(`${Qe}
117
- Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("0.0.1").addCommand(_t).addCommand(Pt).addCommand(qt).addCommand(Yt).addCommand(ir).addCommand($r).parse(process.argv)}en().catch(t=>{o.error("An error occurred:",t),process.exit(1)});
113
+ `),Ue(`http://localhost:${r}`),!0}catch(n){return o.error(`Failed to run TEE simulator: ${n instanceof Error?n.message:String(n)}`),!1}}async stopSimulator(){try{let e=o.startSpinner("Stopping TEE simulator...");return await de("docker stop tee-simulator"),await K(),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return o.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),!1}}static async listLocalImages(){try{let{stdout:e}=await de('docker images --format "{{.Repository}}:{{.Tag}}"'),n=(await O())?.username;return e.split(`
114
+ `).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${n}/`)).map(a=>{let[c,p]=a.split(":"),u=c.split("/");return{name:u.length>1?u[1]:c,tag:p}})}catch(e){return o.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import Ft from"prompts";var It=new no().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 t=>{try{let e=t.username,r=t.password,n=t.registry;if(!e){o.info("First we need your Docker Hub username to check if you are already logged in.");let p=await Ft({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:u=>u.length>0?!0:"Username cannot be empty"});p.username||(o.error("Username is required"),process.exit(1)),e=p.username}let i=new _("",e,n);if(await i.login(e)){o.success(`${e} is logged in to Docker Hub`);return}if(!r){let p=await Ft({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:u=>u.length>0?!0:"Password cannot be empty"});p.password||(o.error("Password is required"),process.exit(1)),r=p.password}await i.login(e,r,n)||(o.error("Failed to login to Docker Hub"),process.exit(1)),await et({username:e,registry:n||null}),o.success("Logged in to Docker Hub successfully")}catch(e){o.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as io}from"commander";import Rt from"path";import Mt from"inquirer";import so from"fs";var Vt=new io().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 t=>{try{let e=await O();if(e||(o.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!t.image){let c=await Mt.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:p=>p.trim()?!0:"Image name is required"}]);t.image=c.image}if(!t.tag){let c=await Mt.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:p=>p.trim()?!0:"Tag is required"}]);t.tag=c.tag}let r=Rt.resolve(process.cwd(),t.file);so.existsSync(r)||(o.info(`Default Dockerfile not found at ${r}`),t.file=await G("Enter the path to your Dockerfile:","Dockerfile","file"));let n=Rt.resolve(process.cwd(),t.file);await new _(t.image,e.username,e.registry).buildImage(n,t.tag)||(o.error("Failed to build Docker image"),process.exit(1)),o.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){o.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ao}from"commander";import Lt from"inquirer";var Nt=new ao().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").action(async t=>{try{let e=await O();e||(o.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let r=t.image,n=t.tag;if(!r||!n){let c=await _.listLocalImages();if(c.length===0&&(o.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let p=Array.from(new Set(c.map(d=>d.name))),{selectedImage:u}=await Lt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:p}]);r=u}if(!n){let p=c.filter(d=>d.name===r).map(d=>d.tag);p.length===0&&(o.error(`No tags found for image ${r}`),process.exit(1));let{selectedTag:u}=await Lt.prompt([{type:"list",name:"selectedTag",message:`Select a tag for ${r}:`,choices:p}]);n=u}}await new _(r,e.username,e.registry).pushImage(n)||(o.error("Failed to push Docker image"),process.exit(1)),o.success(`Docker image ${e.username}/${r}:${n} pushed successfully`)}catch(e){o.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as co}from"commander";import Ee from"inquirer";import Ot from"fs";import Ut from"path";var zt=new co().name("run").description("Run a Docker Compose setup").option("-c, --compose <compose>","Path to docker-compose.yml file").option("-e, --env-file <envFile>","Path to environment variables file").option("--skip-env","Skip environment variables file prompt",!0).action(async t=>{try{let e=t.compose,r=t.envFile;if(e)try{R(e)}catch{o.error(`File not found: ${e}`),process.exit(1)}else{let a=Ut.join(process.cwd(),"docker-compose.yml");if(Ot.existsSync(a)){let{useDefault:p}=await Ee.prompt([{type:"confirm",name:"useDefault",message:"Use docker-compose.yml in current directory?",default:!0}]);p&&(e=a)}if(!e){let{composePath:p}=await Ee.prompt([{type:"input",name:"composePath",message:"Enter path to docker-compose.yml file:",validate:u=>R(u)?!0:"File not found"}]);e=p}}if(!r&&!t.skipEnv){let a=Ut.join(process.cwd(),".env");if(Ot.existsSync(a)){let{useDefault:p}=await Ee.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);p&&(r=a)}if(!r){let{envPath:p}=await Ee.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:u=>{try{return R(u),!0}catch{return`File not found: ${u}`}}}]);r=p}}let n=new _("");if(r){o.info(`Validating env file: ${r}`);try{R(r)}catch{o.error(`File not found: ${r}`),process.exit(1)}o.info(`Running Docker Compose with compose file: ${e} and env file: ${r}`)}else o.info(`Running Docker Compose with compose file: ${e} without env file`);await n.runComposeLocally(e,r)||(o.error("Failed to run Docker Compose"),process.exit(1)),o.success("Docker Compose is running")}catch(e){o.error(`Failed to run Docker Compose: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as mo}from"commander";import M from"inquirer";import fe from"fs";import xe from"path";var jt=new mo().name("generate").description("Generate a Docker Compose file").option("-i, --image <image>","Docker image name to use in the compose file").option("-t, --tag <tag>","Docker image tag to use in the compose file").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").option("--manual","Skip automatic image detection and enter image/tag manually").action(async t=>{try{let e=await O();(!e||!e.username)&&(o.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let r=t.image||"",n=t.tag||"";if((!r||!n)&&!t.manual)try{o.info("Detecting local Docker images...");let u=await _.listLocalImages();if(u.length===0)o.warn("No local Docker images found. You will need to enter image details manually.");else{let d=new Map;if(u.forEach(v=>{d.has(v.name)||d.set(v.name,[]),d.get(v.name)?.push(v.tag)}),r&&!n){let v=d.get(r)||[];if(v.length>0){let{imageTag:y}=await M.prompt([{type:"list",name:"imageTag",message:`Select a tag for ${r}:`,choices:[...v,new M.Separator,"[ Enter manually ]"]}]);y!=="[ Enter manually ]"&&(n=y)}else o.warn(`No tags found for image ${r}. You will need to enter the tag manually.`)}else if(!r){let v=Array.from(d.keys()),{imageName:y}=await M.prompt([{type:"list",name:"imageName",message:"Select a Docker image:",choices:[...v,new M.Separator,"[ Enter manually ]"]}]);if(y!=="[ Enter manually ]"){r=y;let m=d.get(y)||[],{imageTag:l}=await M.prompt([{type:"list",name:"imageTag",message:"Select a tag:",choices:[...m,new M.Separator,"[ Enter manually ]"]}]);l!=="[ Enter manually ]"&&(n=l)}}}}catch(u){o.warn(`Failed to detect local images: ${u instanceof Error?u.message:String(u)}`),o.info("Continuing with manual input...")}if(!r){let{inputImage:u}=await M.prompt([{type:"input",name:"inputImage",message:"Enter Docker image name:",validate:d=>d.trim()?!0:"Image name cannot be empty"}]);r=u}if(!n){let{inputTag:u}=await M.prompt([{type:"input",name:"inputTag",message:`Enter tag for image ${r}:`,validate:d=>d.trim()?!0:"Tag cannot be empty"}]);n=u}let i=t.envFile;if(i)try{R(i)}catch{o.error(`File not found: ${i}`),process.exit(1)}else{let u=xe.join(process.cwd(),".env");if(fe.existsSync(u)){let{useDefault:v}=await M.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);v&&(i=u)}if(!i){let{envPath:v}=await M.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:y=>{try{return R(y),!0}catch{return`File not found: ${y}`}}}]);i=v}}let a=t.output;if(!a&&(a=xe.join(process.cwd(),"docker-compose.yml"),fe.existsSync(a))){let{confirmOverwrite:u}=await M.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${a} already exists. Overwrite?`,default:!1}]);if(!u){let{customPath:d}=await M.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:xe.join(process.cwd(),"docker-generated-compose.yml")}]);a=d}}let c=new _(r,e.username,e.registry);i?o.info(`Generating Docker Compose file for ${r}:${n} using env file: ${i}`):o.info(`Generating Docker Compose file for ${r}:${n} without env file`);let p=await c.buildComposeFile(n,i,t.template);if(p!==a){let u=xe.dirname(a);fe.existsSync(u)||(o.info(`Creating directory: ${u}`),fe.mkdirSync(u,{recursive:!0})),fe.copyFileSync(p,a)}o.success(`Docker Compose file generated successfully: ${a}`)}catch(e){o.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Wt=new lo().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(It).addCommand(Vt).addCommand(zt).addCommand(Nt).addCommand(jt);import{Command as fo}from"commander";import{Command as po}from"commander";var Bt=new po().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",ot).option("-p, --port <port>","Simulator port (default: 8090)","8090").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async t=>{try{if(t.type==="docker")await new _("").runSimulator(t.image,t.port)||(o.error("Failed to start TEE simulator"),process.exit(1));else if(t.type==="native")if(xt()||await _t(),await Se()){o.success("TEE simulator is already running");return}else{let r=$t();o.success("TEE simulator started successfully")}else o.error("Invalid simulator type"),process.exit(1)}catch(e){o.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as uo}from"commander";var Gt=new uo().name("stop").description("Stop the TEE simulator").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async t=>{try{t.type==="docker"?await new _("").stopSimulator()||(o.error("Failed to stop TEE simulator"),process.exit(1)):t.type==="native"?await Tt()||(o.error("Failed to stop TEE simulator"),process.exit(1)):(o.error("Invalid simulator type"),process.exit(1))}catch(e){o.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Kt=new fo().name("simulator").description("TEE simulator commands").addCommand(Bt).addCommand(Gt);import{Command as Fo}from"commander";import{Command as ho}from"commander";import go from"inquirer";import{z as Ht}from"zod";async function _e(){try{let t=await $.get(x.CVMS(0));return Ht.array(Me).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function T(t){let r=(await _e()).find(n=>n.hosted?.app_id===t||`app_${n.hosted?.app_id}`===t);if(!r)o.error(`CVM with App ID ${t} not detected`),process.exit(1);else return o.success(`CVM with App ID ${t} detected`),r.hosted?.app_id}async function te(t){try{let e=await $.get(x.CVM_BY_APP_ID(t));return dt.parse(e)}catch(e){throw new Error(`Failed to get CVM by App ID: ${e instanceof Error?e.message:String(e)}`)}}async function qt(t){try{let e=await $.post(x.CVM_PUBKEY,t);return ut.parse(e)}catch(e){throw new Error(`Failed to get pubkey from CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Zt(t){try{let e=await $.post(x.CVM_FROM_CONFIGURATION,t);return pt.parse(e)}catch(e){throw e instanceof Ht.ZodError?(o.error("Schema validation error:",JSON.stringify(e.errors,null,2)),o.error("API response:",JSON.stringify(e.format(),null,2)),new Error(`Response validation failed: ${JSON.stringify(e.errors)}`)):new Error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Jt(t){try{return await $.post(x.CVM_START(t)),!0}catch(e){throw new Error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Yt(t){try{return await $.post(x.CVM_STOP(t)),!0}catch(e){throw new Error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Xt(t){try{return await $.post(x.CVM_RESTART(t)),!0}catch(e){throw new Error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Qt(t,e){try{let r=await $.put(x.CVM_UPGRADE(t),e);return gt.parse(r)}catch(r){throw new Error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`)}}async function er(t){try{return await $.delete(x.CVM_BY_APP_ID(t)),!0}catch(e){throw new Error(`Failed to delete CVM: ${e instanceof Error?e.message:String(e)}`)}}async function P(){let t=o.startSpinner("Fetching available CVMs"),e=await _e();if(t.stop(!0),!e||e.length===0){o.info("No CVMs found for your account");return}let r=e.map(i=>{let a=i.hosted?.app_id||i.hosted?.id,c=i.name||i.hosted&&i.hosted.name,p=i.status||i.hosted&&i.hosted.status;return{name:`${c||"Unnamed"} (${a}) - Status: ${p||"Unknown"}`,value:a}}),{selectedCvm:n}=await go.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:r}]);return n}async function tr(t){try{return await $.get(x.CVM_ATTESTATION(t))}catch(e){throw new Error(`Failed to get attestation information: ${e instanceof Error?e.message:String(e)}`)}}async function rr(t,e,r,n,i){try{let a={};if(e!==void 0&&(a.vcpu=e),r!==void 0&&(a.memory=r),n!==void 0&&(a.disk_size=n),i!==void 0&&(a.allow_restart=i),Object.keys(a).length===0)throw new Error("At least one resource parameter must be provided");return await $.patch(x.CVM_RESIZE(t),a),!0}catch(a){throw new Error(`Failed to resize CVM: ${a instanceof Error?a.message:String(a)}`)}}import je from"chalk";var or=new ho().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=o.startSpinner("Fetching CVMs"),r=await _e();if(e.stop(!0),!r||r.length===0){o.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(r,null,2));return}r.forEach(n=>{o.keyValueTable({"App ID":`app_${n.hosted.app_id}`,Name:n.name,Status:n.status==="running"?je.green(n.status):n.status==="stopped"?je.red(n.status):je.yellow(n.status),"Node Info URL":n.hosted.app_url,"App URL":`${J}/dashboard/cvms/app_${n.hosted.app_id}`})}),o.success(`Found ${r.length} CVMs:`)}catch(e){o.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as yo}from"commander";import We from"chalk";var nr=new yo().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(t,e)=>{try{if(t)t=await T(t);else if(t=await P(),!t){o.info("No CVMs found or selection cancelled");return}let r=o.startSpinner(`Fetching CVM with App ID ${t}`),n=await te(t);if(r.stop(!0),n||(o.error(`CVM with App ID ${t} not found`),process.exit(1)),e.json){console.log(JSON.stringify(n,null,2));return}o.keyValueTable({Name:n.name,"App ID":`app_${n.app_id}`,Status:n.status==="running"?We.green(n.status):n.status==="stopped"?We.red(n.status):We.yellow(n.status),vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"TEEPod ID":n.teepod_id,"App URL":`${J}/dashboard/cvms/app_${n.app_id}`})}catch(r){o.error(`Failed to get CVM details: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as vo}from"commander";var ir=new vo().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 t=>{try{if(t)t=await T(t);else if(t=await P(),!t)return;let e=o.startSpinner(`Starting CVM with App ID ${t}`);await Jt(t),e.stop(!0),o.success(`CVM with App ID ${t} started successfully`)}catch(e){o.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as bo}from"commander";var sr=new bo().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 t=>{try{if(t)t=await T(t);else if(t=await P(),!t)return;let e=o.startSpinner(`Stopping CVM with App ID ${t}`);await Yt(t),e.stop(!0),o.success(`CVM with App ID ${t} stopped successfully`)}catch(e){o.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Co}from"commander";var ar=new Co().name("restart").description("Restart a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async t=>{try{if(t)t=await T(t);else if(t=await P(),!t)return;let e=o.startSpinner(`Restarting CVM with App ID ${t}`);await Xt(t),e.stop(!0),o.success(`CVM with App ID ${t} restarted successfully`)}catch(e){o.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as wo}from"commander";import $e from"chalk";var cr=new wo().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(t,e)=>{try{if(t)t=await T(t);else{o.info("No CVM specified, fetching available CVMs...");let n=await P();if(!n)return;t=n}o.info(`Fetching attestation information for CVM ${t}...`);let r=o.startSpinner("Fetching attestation information");try{let n=await tr(t);if(r.stop(!0),!n||Object.keys(n).length===0){o.info("No attestation information found");return}if(e?.json){o.info(JSON.stringify(n,null,2));return}o.success("Attestation Summary:");let i={Status:n.is_online?$e.green("Online"):$e.red("Offline"),"Public Access":n.is_public?$e.green("Enabled"):$e.yellow("Disabled"),Error:n.error||"None",Certificates:`${n.app_certificates?.length||0} found`};o.keyValueTable(i,{borderStyle:"rounded"}),n.app_certificates&&n.app_certificates.length>0&&n.app_certificates.forEach((a,c)=>{o.success(`Certificate #${c+1} (${a.position_in_chain===0?"End Entity":"CA"}):`);let p={Subject:`${a.subject.common_name||"Unknown"}${a.subject.organization?` (${a.subject.organization})`:""}`,Issuer:`${a.issuer.common_name||"Unknown"}${a.issuer.organization?` (${a.issuer.organization})`:""}`,"Serial Number":a.serial_number,Validity:`${new Date(a.not_before).toLocaleString()} to ${new Date(a.not_after).toLocaleString()}`,Fingerprint:a.fingerprint,"Signature Algorithm":a.signature_algorithm,"Is CA":a.is_ca?"Yes":"No","Position in Chain":a.position_in_chain};o.keyValueTable(p,{borderStyle:"single"})}),n.tcb_info&&(o.success("Trusted Computing Base (TCB) Information:"),o.keyValueTable(n.tcb_info,{borderStyle:"single"}))}catch(n){throw r.stop(!0),n}}catch(r){o.error(`Failed to get attestation information: ${r instanceof Error?r.message:String(r)}`)}});import{Command as So}from"commander";import{encryptEnvVars as Eo}from"@phala/dstack-sdk/encrypt-env-vars";import mr from"fs";import xo from"path";import he from"inquirer";import ko from"fs";var ge=(t,e)=>{let r={};if(t){for(let n of t)if(n.includes("=")){let[i,a]=n.split("=");i&&a&&(r[i]=a)}}if(e){let n=ko.readFileSync(e,"utf8");for(let i of n.split(`
115
+ `))if(!(!i.trim()||i.trim().startsWith("#"))&&i.includes("=")){let[a,...c]=i.split("="),p=c.join("="),u=p.search(/\s+#/);u!==-1&&(p=p.substring(0,u).trim()),a&&p&&(r[a.trim()]=p.trim())}}return Object.entries(r).map(([n,i])=>({key:n,value:i}))};var lr=new So().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",String(se)).option("--memory <memory>","Memory in MB",String(ae)).option("--disk-size <diskSize>","Disk size in GB",String(ce)).option("--teepod-id <teepodId>","TEEPod ID to use",nt).option("--image <image>","Version of dstack image to use",it).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 t=>{try{if(!t.name){let{name:m}=await he.prompt([{type:"input",name:"name",message:"Enter a name for the CVM:",validate:l=>l.trim()?!0:"CVM name is required"}]);t.name=m}if(!t.compose){let l=ke(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");t.compose=await G("Enter the path to your Docker Compose file:",l,"file")}let e=xo.resolve(t.compose);mr.existsSync(e)||(o.error(`Docker Compose file not found: ${e}`),process.exit(1));let r=mr.readFileSync(e,"utf8");await K();let n=[];if(t.envFile)try{n=ge([],t.envFile)}catch(m){o.error(`Failed to read environment file: ${m instanceof Error?m.message:String(m)}`),process.exit(1)}else if(!t.skipEnv)if(await he.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!1}]))o.info("Skipping environment variable prompt");else{let l=await G("Enter the path to your environment file:",".env","file");n=ge([],l)}let i=[];if(t.vcpu===String(se)&&i.push({type:"input",name:"vcpu",message:`Enter number of vCPUs (default: ${se}):`,default:String(se),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.memory===String(ae)&&i.push({type:"input",name:"memory",message:`Enter memory in MB (default: ${ae}):`,default:String(ae),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.diskSize===String(ce)&&i.push({type:"input",name:"diskSize",message:`Enter disk size in GB (default: ${ce}):`,default:String(ce),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),i.length>0){let m=await he.prompt(i);m.vcpu&&(t.vcpu=m.vcpu),m.memory&&(t.memory=m.memory),m.diskSize&&(t.diskSize=m.diskSize)}if(!t.teepodId){let m=o.startSpinner("Fetching available TEEPods"),l=await B();m.stop(!0),l.length===0&&(o.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:f}=await he.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:l.map(b=>({name:`${b.name}`,value:b.teepod_id}))}]),h=l.find(b=>b.teepod_id===f);h||(o.error("Failed to find selected TEEPod"),process.exit(1)),o.info(`Selected TEEPod: ${h.name}`),t.teepodId=h.teepod_id}if(!t.image){let l=(await we(t.teepodId)).map(h=>({name:`${h.name}`,value:h.name})),{selectedImage:f}=await he.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:l}]);t.image=f.value}let a={teepod_id:t.teepodId||3,name:t.name,image:t.image||"dstack-dev-0.3.5",vcpu:parseInt(t.vcpu),memory:parseInt(t.memory),disk_size:parseInt(t.diskSize),compose_manifest:{docker_compose_file:r,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:t.name,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},c=o.startSpinner("Getting public key from CVM"),p=await qt(a);c.stop(!0),p||(o.error("Failed to get public key from CVM"),process.exit(1));let u=o.startSpinner("Encrypting environment variables"),d=await Eo(n,p.app_env_encrypt_pubkey);u.stop(!0),t.debug&&(o.debug("Public key:",p.app_env_encrypt_pubkey),o.debug("Encrypted environment variables:",d),o.debug("Environment variables:",JSON.stringify(n)));let v=o.startSpinner("Creating CVM"),y=await Zt({...a,encrypted_env:d,app_env_encrypt_pubkey:p.app_env_encrypt_pubkey,app_id_salt:p.app_id_salt});v.stop(!0),y||(o.error("Failed to create CVM"),process.exit(1)),o.success("CVM created successfully"),o.info(`CVM ID: ${y.id}`),o.info(`Name: ${y.name}`),o.info(`Status: ${y.status}`),o.info(`App ID: ${y.app_id}`),y.app_url?o.info(`App URL: ${y.app_url}`):o.info(`App URL: ${J}/dashboard/cvms/app_${y.app_id}`),o.info(""),o.info("Your CVM is being created. You can check its status with:"),o.info(`phala cvms get ${y.app_id}`)}catch(e){o.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as _o}from"commander";import $o from"inquirer";var pr=new _o().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(t,e)=>{try{if(t)t=await T(t);else if(t=await P(),!t)return;if(!e.force){let{confirm:i}=await $o.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID ${t}? This action cannot be undone.`,default:!1}]);if(!i){o.info("Deletion cancelled");return}}let r=o.startSpinner(`Deleting CVM ${t}`),n=await er(t);r.stop(!0),n||(o.error(`Failed to delete CVM ${t}`),process.exit(1)),o.success(`CVM ${t} deleted successfully`)}catch(r){o.error(`Failed to delete CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as To}from"commander";import Po from"fs";import{encryptEnvVars as Do}from"@phala/dstack-sdk/encrypt-env-vars";var ur=new To().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(t,e)=>{try{if(t)t=await T(t);else{o.info("No CVM specified, fetching available CVMs...");let d=await P();if(!d)return;t=d}let r=o.startSpinner(`Fetching current configuration for CVM ${t}`),n=await te(t);if(r.stop(!0),n||(o.error(`CVM with App ID ${t} not found`),process.exit(1)),!e.compose){let v=ke(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");e.compose=await G("Enter the path to your Docker Compose file:",v,"file")}let i="";if(e.compose)try{i=Po.readFileSync(e.compose,"utf8")}catch(d){o.error(`Failed to read Docker Compose file: ${d instanceof Error?d.message:String(d)}`),process.exit(1)}await K();let a="";if(e.envFile){let d=[];if(e.envFile)try{d=ge([],e.envFile),a=await Do(d,n.encrypted_env_pubkey)}catch(v){o.error(`Failed to read environment file: ${v instanceof Error?v.message:String(v)}`),process.exit(1)}}let c={compose_manifest:{docker_compose_file:i,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${e.appId}`},encrypted_env:a,allow_restart:!0},p=o.startSpinner(`Upgrading CVM ${t}`),u=await Qt(t,c);p.stop(!0),u||(o.error("Failed to upgrade CVM"),process.exit(1)),o.success(`CVM ${t} upgraded successfully`),u.detail&&o.info(`Details: ${u.detail}`)}catch(r){o.error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Ao}from"commander";import ye from"inquirer";import j from"chalk";var dr=new Ao().name("resize").description("Resize resources for a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").option("-v, --vcpu <vcpu>","Number of virtual CPUs").option("-m, --memory <memory>","Memory size in MB").option("-d, --disk-size <diskSize>","Disk size in GB").option("-r, --allow-restart <allowRestart>","Allow restart of the CVM if needed for resizing").option("-y, --yes","Automatically confirm the resize operation").action(async(t,e)=>{try{if(t)t=await T(t);else if(t=await P(),!t){o.info("No CVMs found or selection cancelled");return}let r=await te(t),n=e.vcpu,i=e.memory,a=e.diskSize,c=e.allowRestart;n||(n=(await ye.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.vcpu,filter:y=>parseInt(y)}])).vcpu),i||(i=(await ye.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.memory,filter:y=>parseInt(y)}])).memory),a||(a=(await ye.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:y=>{let m=parseInt(y);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:r.disk_size,filter:y=>parseInt(y)}])).diskSize),c||(c=(await ye.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let p=`Are you sure you want to resize CVM ${t} with the following changes:
116
+ `;if(o.keyValueTable({vCPUs:r.vcpu!==n?`${j.red(r.vcpu)} -> ${j.green(n)}`:r.vcpu,Memory:r.memory!==i?`${j.red(r.memory)} MB -> ${j.green(i)} MB`:r.memory,"Disk Size":r.disk_size!==a?`${j.red(r.disk_size)} GB -> ${j.green(a)} GB`:r.disk_size,"Allow Restart":c?j.green("Yes"):j.red("No")}),!e.yes){let{confirm:v}=await ye.prompt([{type:"confirm",name:"confirm",message:p,default:!1}]);if(!v){o.info("Resize operation cancelled");return}}let u=o.startSpinner(`Resizing CVM with App ID ${t}`);await rr(t,n,i,a,c?1:0),u.stop(!0),o.success(`CVM with App ID ${t} resized successfully`)}catch(r){o.error(`Failed to resize CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var fr=new Fo().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(or).addCommand(nr).addCommand(lr).addCommand(ur).addCommand(ir).addCommand(sr).addCommand(ar).addCommand(cr).addCommand(pr).addCommand(dr);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function Ro(){new Io().name("phala").description(`${qe}
117
+ Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("0.0.1").addCommand(wt).addCommand(fr).addCommand(Wt).addCommand(Kt).addCommand(Et).parse(process.argv)}Ro().catch(t=>{o.error("An error occurred:",t),process.exit(1)});
118
118
  //# sourceMappingURL=index.js.map