phala 0.0.1-alpha-9 → 0.0.1-alpha-11
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/README.md +14 -139
- package/dist/index.js +18 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env bun
|
2
|
-
var
|
2
|
+
var pr=Object.defineProperty;var ur=(t,e,r)=>e in t?pr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var Be=(t,e,r)=>(ur(t,typeof e!="symbol"?e+"":e,r),r);import{Command as _o}from"commander";import Ge from"chalk";var Ke=Ge.hex("#cdfa50"),He=Ke(`
|
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 yr=Object.defineProperty;var vr=(t,e,r)=>e in t?yr(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
|
-
`),
|
24
|
+
`),Do=Ke(`
|
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 yr=Object.defineProperty;var vr=(t,e,r)=>e in t?yr(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
|
-
`),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'
|
46
|
+
`),Ao=Ge.cyan("PHALA TEE CLOUD CLI");import{Command as Vr}from"commander";import{Command as Ir}from"commander";import V from"fs";import De from"path";import Z from"os";import be from"crypto";import S from"chalk";function dr(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 dr(t).length}function re(t,e){if(!t)return[""];if(q(t)<=e)return[t];let r=[],o="",i=0,a=t.split(/(\s+)/).filter(c=>c.trim().length>0);for(let c of a){let p=q(c);if(p>e){o&&(r.push(o),o="",i=0),r.push(c);continue}i+p+(i>0?1:0)>e?(r.push(o),o=c,i=p):o?(o=`${o} ${c}`,i+=p+1):(o=c,i=p)}return o&&r.push(o),r}var n={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(o=>({key:o,header:o.charAt(0).toUpperCase()+o.slice(1)}));$e(t,{columns:r,borderStyle:"rounded",headerStyle:o=>S.cyan.bold(o)})}else $e(t,{columns:e,borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)});else $e(t,{borderStyle:"rounded",headerStyle:r=>S.cyan.bold(r)})},keyValueTable:(t,e)=>{let o={...{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"},R;k.includes("_")?R=k.split("_").map(F=>F.charAt(0).toUpperCase()+F.slice(1).toLowerCase()).join(" "):k.includes("-")?R=k.split("-").map(F=>F.charAt(0).toUpperCase()+F.slice(1).toLowerCase()).join(" "):R=k.charAt(0).toUpperCase()+k.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let F of E){let O=new RegExp(`\\b${F.toLowerCase()}\\b`,"gi");R=R.replace(O,F)}for(let[F,O]of Object.entries(D)){let ve=new RegExp(`\\b${F}\\b`,"gi");R=R.replace(ve,O)}return R},valueFormatter:k=>String(k??"")},...e},{include:i,exclude:a,keyFormatter:c,valueFormatter:p,formatKeys:f,keyWidth:g,valueWidth:v,borderStyle:y,enableTextWrapping:m,maxDepth:l}=o,u=Object.keys(t);if(i&&(u=u.filter(k=>i.includes(k))),a&&(u=u.filter(k=>!a.includes(k))),u.length===0){console.log(S.yellow("No properties to display"));return}let h=u.map(k=>{let E=t[k],D;return E==null?D="":typeof E=="object"&&!Array.isArray(E)?D=qe(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:f&&c?c(k):k,value:D}}),b=Ze(),d=g,C=v;if(d||(d=Math.max(...h.map(k=>q(k.key)),10),d=Math.min(d,Math.floor(b/3))),!C){C=Math.max(...h.map(D=>q(D.value)),10),C+=3;let k=7,E=b-d-k;C=Math.min(C,E)}let w=fr(y),j=`${w.topLeft}${w.horizontal.repeat(d+2)}${w.topT}${w.horizontal.repeat(C+2)}${w.topRight}`,L=`${w.leftT}${w.horizontal.repeat(d+2)}${w.cross}${w.horizontal.repeat(C+2)}${w.rightT}`;console.log(j),console.log(L),h.forEach((k,E)=>{let D=m?re(k.key,d):[k.key],R=m?re(k.value,C):[k.value],F=Math.max(D.length,R.length);for(let O=0;O<F;O++){let ve=D[O]||"",We=R[O]||"",mr=ve+" ".repeat(Math.max(0,d-q(ve))),lr=We+" ".repeat(Math.max(0,C-q(We)));console.log(`${w.vertical} ${mr} ${w.vertical} ${lr} ${w.vertical}`)}E<h.length-1&&console.log(`${w.leftT}${w.horizontal.repeat(d+2)}${w.cross}${w.horizontal.repeat(C+2)}${w.rightT}`)});let Te=`${w.bottomLeft}${w.horizontal.repeat(d+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 o=e?S.green("\u2713"):S.red("\u2717"),i=r?`: ${r}`:"";console.log(`${o}${i}`)}}),break(){console.log("")}};function qe(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 o=[];for(let[i,a]of Object.entries(t))a==null?o.push(`${i}: `):typeof a=="object"?o.push(`${i}: ${qe(a,e+1,r)}`):o.push(`${i}: ${a}`);return o.join(", ")}function fr(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 Ze(){return process.stdout.columns||80}function gr(t,e,r={}){let o=Ze(),i=r.borderChars??3,c=(r.additionalBorderWidth??1)+e.length*i,p=o-c,f={},g=0,v=0;for(let l of e){let u=l.key;if(l.fixedWidth!==void 0){f[u]=l.fixedWidth,g+=l.fixedWidth;continue}let h=l.minWidth??l.header.length,b;l.getWidth?b=Math.max(h,l.header.length,...t.map(d=>l.getWidth(d))):l.getValue?b=Math.max(h,l.header.length,...t.map(d=>String(l.getValue(d)||"").length)):b=Math.max(h,l.header.length,...t.map(d=>String(d[l.key]||"").length)),f[u]=b,g+=b,v+=l.weight??1}let y=Math.max(0,p-g);if(y>0&&v>0)for(let l of e){let u=l.key;if(l.fixedWidth===void 0&&l.weight){let h=Math.floor(y*(l.weight/v));f[u]+=h}}let m=Object.values(f).reduce((l,u)=>l+u,0)+c;if(m>o){let l=p/(m-c),u={};for(let h of e){let b=h.key,d=h.minWidth??h.header.length;u[b]=Math.max(d,Math.floor(f[b]*l))}return u}return f}function $e(t,e={}){if(e.keyValueMode&&t.length===1){let m=t[0],l=[];e.columns||(e.columns=Object.keys(m).map(u=>({key:u,header:u.charAt(0).toUpperCase()+u.slice(1).replace(/([A-Z])/g," $1")})));for(let u of e.columns){let h=String(u.key),b;if(u.accessor)b=u.accessor(m);else if(typeof u.key=="string"&&u.key.includes(".")){let d=u.key.split("."),C=m;for(let w of d){if(C==null){b="";break}C=C[w]}b=C}else b=m[u.key];u.formatter&&(b=u.formatter(b)),l.push({key:u.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 o={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:m=>S.bold(m),cellStyle:m=>m,enableTextWrapping:!0},...e},i=o.columns;if(i)i=i.map(m=>({...m,enableTextWrapping:m.enableTextWrapping!==void 0?m.enableTextWrapping:o.enableTextWrapping}));else{let m=t[0];i=Object.keys(m).map(l=>({key:l,header:l.charAt(0).toUpperCase()+l.slice(1),enableTextWrapping:o.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"}}[o.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 u=m.key.split("."),h=l;for(let b of u){if(h==null)return"";h=h[b]}return h??""}return l[m.key]??""}})),f=gr(t,p),g=i.map((m,l)=>({...m,width:f[p[l].key]})),v=g.map(m=>m.header||String(m.key)),y=(m,l)=>{let u=g.map(d=>{let C;if(d.accessor)C=d.accessor(m);else if(typeof d.key=="string"&&d.key.includes(".")){let j=d.key.split("."),L=m;for(let Te of j){if(L==null){C="";break}L=L[Te]}C=L??""}else C=m[d.key]??"";let w=d.formatter?d.formatter(C):String(C||"");return d.enableTextWrapping?{lines:re(w,d.width),key:String(d.key)}:{lines:[w.length>d.width?w.substring(0,d.width-1)+"\u2026":w],key:String(d.key)}}),h=Math.max(...u.map(d=>d.lines.length)),b=[];for(let d=0;d<h;d++){let C=u.map((w,j)=>{let L=w.lines[d]||"";return o.cellStyle(L.padEnd(g[j].width),l,w.key)});b.push(C)}return b};if(o.border){let m=c.topLeft+g.map(u=>c.horizontal.repeat(u.width+2)).join(c.topT)+c.topRight;if(console.log(m),o.includeHeaders){let u=g.map((d,C)=>({lines:d.enableTextWrapping?re(v[C],d.width):[v[C]],width:d.width})),h=Math.max(...u.map(d=>d.lines.length));for(let d=0;d<h;d++){let C=c.vertical+u.map(w=>{let j=w.lines[d]||"";return" "+o.headerStyle(j.padEnd(w.width))+" "}).join(c.vertical)+c.vertical;console.log(C)}let b=c.leftT+g.map(d=>c.horizontal.repeat(d.width+2)).join(c.cross)+c.rightT;console.log(b)}t.forEach((u,h)=>{let b=y(u,h);if(b.forEach(d=>{console.log(c.vertical+d.map(C=>` ${C} `).join(c.vertical)+c.vertical)}),h<t.length-1&&b.length>1){let d=c.leftT+g.map(C=>c.horizontal.repeat(C.width+2)).join(c.cross)+c.rightT;console.log(d)}});let l=c.bottomLeft+g.map(u=>c.horizontal.repeat(u.width+2)).join(c.bottomT)+c.bottomRight;console.log(l)}else{if(o.includeHeaders){let m=g.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(d=>{let C=d.lines[h]||"";return o.headerStyle(C.padEnd(d.width))}).join(" ");console.log(b)}let u=g.map(h=>"\u2500".repeat(h.width)).join(" ");console.log(u)}t.forEach((m,l)=>{let u=y(m,l);u.forEach(h=>{console.log(h.join(" "))}),l<t.length-1&&u.length>1&&console.log("")})}console.log(`Total: ${t.length} rows`)}var oe=De.join(Z.homedir(),".phala-cloud"),ne=De.join(oe,"api-key"),Pe=De.join(oe,"docker-credentials.json");function Je(){if(!V.existsSync(oe))try{V.mkdirSync(oe,{recursive:!0})}catch(t){throw n.error(`Failed to create directory ${oe}:`,t),t}}function Ye(){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 hr(t){try{let e=Ye(),r=be.randomBytes(16),o=be.createCipheriv("aes-256-cbc",e.slice(0,32),r),i=o.update(t,"utf8","hex");return i+=o.final("hex"),r.toString("hex")+":"+i}catch(e){throw n.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function yr(t){try{let e=Ye(),r=t.split(":");if(r.length!==2)throw new Error("Invalid encrypted format");let o=Buffer.from(r[0],"hex"),i=r[1],a=be.createDecipheriv("aes-256-cbc",e.slice(0,32),o),c=a.update(i,"hex","utf8");return c+=a.final("utf8"),c}catch(e){throw n.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function Xe(t){Je();try{let e=hr(t);V.writeFileSync(ne,e,{mode:384})}catch(e){throw n.error("Failed to save API key:",e),e}}async function Ce(){try{if(V.existsSync(ne)){let t=V.readFileSync(ne,"utf8").trim();return yr(t)}return null}catch(t){return n.error("Failed to read API key:",t),null}}async function ie(){try{V.existsSync(ne)?(V.unlinkSync(ne),n.success("API key removed successfully.")):n.warn("No API key found to remove.")}catch(t){throw n.error("Failed to remove API key:",t),t}}async function Qe(t){Je();try{V.writeFileSync(Pe,JSON.stringify(t,null,2),{mode:384}),n.success("Docker information saved successfully.")}catch(e){throw n.error("Failed to save Docker information:",e),e}}async function N(){try{if(V.existsSync(Pe)){let t=V.readFileSync(Pe,"utf8");return JSON.parse(t)}return null}catch(t){return n.error("Failed to read Docker credentials:",t),null}}import Fr from"prompts";import vr from"axios";var Ae=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",J=process.env.CLOUD_URL||"https://cloud.phala.network",et="0.0.1";var tt="phalanetwork/tappd-simulator:latest",se=2,ae=4096,ce=40,rt="3",ot="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`},nt=`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:`,
|
91
|
+
postgres-data:`,it=`version: '3.8'
|
92
92
|
services:
|
93
93
|
app:
|
94
94
|
image: {{imageName}}:{{tag}}
|
@@ -99,20 +99,19 @@ services:
|
|
99
99
|
{{#each envVars}} - {{{this}}}
|
100
100
|
{{/each}}
|
101
101
|
restart: always
|
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
|
-
`),
|
104
|
-
Open in Web UI at https://phala.cloud/dashboard`)}catch(e){
|
105
|
-
[${
|
106
|
-
`)}return a.background&&(
|
107
|
-
`);
|
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=>{
|
109
|
-
`).filter(l=>l&&!l.startsWith("#")).map(l=>{let
|
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(`
|
102
|
+
`;function Ie(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var Fe=class{client;apiKey=null;constructor(e){n.debug(`Creating API client with base URL: ${e}`),this.client=vr.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${et}`}}),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"');n.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return r.headers["X-API-Key"]=this.apiKey,n.debug(`Making request to: ${r.baseURL}${r.url}`),r}),this.client.interceptors.response.use(r=>(n.debug(`Received successful response from: ${r.config.url}`),r),r=>{if(r.response){let{status:o,data:i}=r.response;n.debug(`Received error response: ${o} - ${Ie(i)}`),o===401?n.error("Authentication failed. Please check your API key."):o===403?n.error("You do not have permission to perform this action."):o===404?n.error("Resource not found."):n.error(`API Error (${o}): ${i.message||Ie(i)}`)}else r.request?(n.error("No response received from the server. Please check your internet connection."),n.debug(`Request details: ${Ie(r.request).substring(0,200)}...`)):n.error(`Error: ${r.message}`);return Promise.reject(r)})}async get(e,r){try{return n.debug(`GET request to: ${e}`),(await this.client.get(e,r)).data}catch(o){throw n.debug(`GET request failed: ${o instanceof Error?o.message:String(o)}`),o}}async post(e,r,o){try{return n.debug(`POST request to: ${e}`),(await this.client.post(e,r,o)).data}catch(i){throw n.debug(`POST request failed: ${i instanceof Error?i.message:String(i)}`),i}}async put(e,r,o){try{return n.debug(`PUT request to: ${e}`),(await this.client.put(e,r,o)).data}catch(i){throw n.debug(`PUT request failed: ${i instanceof Error?i.message:String(i)}`),i}}async delete(e,r){try{return n.debug(`DELETE request to: ${e}`),(await this.client.delete(e,r)).data}catch(o){throw n.debug(`DELETE request failed: ${o instanceof Error?o.message:String(o)}`),o}}async patch(e,r,o){try{return n.debug(`PATCH request to: ${e}`),(await this.client.patch(e,r,o)).data}catch(i){throw n.debug(`PATCH request failed: ${i instanceof Error?i.message:String(i)}`),i}}};n.debug(`Initializing API client with URL: ${Ae}`);var _=new Fe(Ae);import{z as s}from"zod";import{INVALID as br,ParseStatus as Cr,ZodIssueCode as Y,ZodParsedType as st,ZodType as wr,addIssueToContext as X,z as at}from"zod";var kr="ZodDecimal",Sr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,le=class extends wr{_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)!==st.number){let a=this._getOrReturnCtx(e);return X(a,{code:Y.invalid_type,expected:st.number,received:a.parsedType}),br}let o,i=new Cr;for(let a of this._def.checks)if(a.kind==="precision"){let c=e.data.toString().match(Sr);Math.max((c[1]?c[1].length:0)-(c[2]?parseInt(c[2],10):0),0)>a.value&&(o=this._getOrReturnCtx(e,o),X(o,{code:Y.custom,message:a.message,params:{precision:a.value}}),i.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(o=this._getOrReturnCtx(e,o),X(o,{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)&&(o=this._getOrReturnCtx(e,o),X(o,{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)&&(o=this._getOrReturnCtx(e,o),X(o,{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)||(o=this._getOrReturnCtx(e,o),X(o,{code:Y.not_finite,message:a.message}),i.dirty()));return{status:i.value,value:e.data}}setLimit(e,r,o,i){return new le({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:o,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 o of this._def.checks){if(o.kind==="finite")return!0;o.kind==="min"?(r===null||o.value>r)&&(r=o.value):o.kind==="max"&&(e===null||o.value<e)&&(e=o.value)}return Number.isFinite(r)&&Number.isFinite(e)}},me=le;Be(me,"create",e=>new le({checks:[],typeName:kr,coerce:e?.coerce??!1}));var ct=at.object({template:at.string().min(1,"Template cannot be empty")});var Er=s.object({password:s.string(),registry:s.string().nullable(),username:s.string()}),xr=s.object({docker_compose_file:s.string(),docker_config:Er.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()}),_r=s.object({name:s.string(),image:s.string(),compose_file:xr,vcpu:s.number(),memory:s.number(),disk_size:s.number(),ports:s.array(s.any())}),Tr=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:_r,exited_at:s.string(),boot_progress:s.string(),boot_error:s.string(),shutdown_progress:s.string(),image_version:s.string()}),$r=s.object({id:s.number(),username:s.string()}),Pr=s.object({id:s.number(),name:s.string()}),Me=s.object({hosted:Tr,name:s.string(),managed_user:$r,node:Pr,listed:s.boolean(),status:s.string(),in_progress:s.boolean(),dapp_dashboard_url:s.string().nullable(),syslog_endpoint:s.string(),allow_upgrade:s.boolean()}),mt=s.object({id:s.number(),name:s.string(),status:s.string(),teepod_id:s.number().nullable(),teepod:s.object({id:s.number(),name:s.string()}).nullable(),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()}),lt=s.object({app_env_encrypt_pubkey:s.string(),app_id_salt:s.string()}),pt=s.object({id:s.number(),teepod_id:s.number().nullable(),teepod:s.object({id:s.number(),name:s.string()}).nullable(),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()}),ut=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()}),sn=s.array(Me),dt=s.object({detail:s.string()}),an=s.object({key:s.string(),value:s.string()}),Re=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()}),Dr=s.object({teepod_id:s.number().nullable(),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(Re).optional()}),Ar=s.object({max_instances:s.number().nullable(),max_vcpu:s.number().nullable(),max_memory:s.number().nullable(),max_disk:s.number().nullable()}),ft=s.object({tier:s.string(),capacity:Ar,nodes:s.array(Dr)});function gt(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function pe(){try{n.debug(`Fetching user info from ${x.USER_INFO}`);let t=await _.get(x.USER_INFO);n.debug(`Received response: ${gt(t)}`);try{return ut.parse(t)}catch(e){throw n.error(`Failed to parse user info response: ${e}`),n.debug(`Response structure: ${gt(t)}`),e}}catch(t){throw n.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 ht=new Ir().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 Fr({type:"password",name:"apiKey",message:"Enter your API key:",validate:async o=>{if(o.length===0)return"API key cannot be empty";try{if(await Xe(o),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";n.success(`Welcome ${e.username}! API key validated and saved successfully
|
103
|
+
`),n.info(`
|
104
|
+
Open in Web UI at https://phala.cloud/dashboard`)}catch(e){n.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Mr}from"commander";var yt=new Mr().name("logout").description("Remove the stored API key").action(async()=>{try{await ie(),n.success("API key removed successfully")}catch(t){n.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Rr}from"commander";var vt=new Rr().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){n.warn('Not authenticated. Please set an API key with "phala auth login"');return}n.debug(`Using API key: ${e.substring(0,5)}...`);let r=n.startSpinner("Checking authentication status");try{let o=await pe();if(r.stop(!0),t.json){console.log(JSON.stringify(o,null,2));return}n.success(`Authenticated as ${o.username}`),n.break();let i={Username:o.username,Email:o.email,Role:o.role,Team:`${o.team_name} (${o.team_tier})`,Credits:`$${o.credits}`};o.trial_ended_at&&(i["Trial Ended At"]=o.trial_ended_at),console.table(i)}catch(o){r.stop(!1),n.error("Authentication failed. Your API key may be invalid or expired."),n.info('Please set a new API key with "phala auth login"'),t.debug&&n.debug(`Error details: ${o instanceof Error?o.message:String(o)}`)}}catch(e){n.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var bt=new Vr().name("auth").description("Authenticate with Phala Cloud").addCommand(ht).addCommand(yt).addCommand(vt);import{Command as zr}from"commander";import{Command as Nr}from"commander";import{z as Lr}from"zod";async function W(){try{let t=await _.get(x.TEEPODS);return ft.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 W()).find(i=>i.teepod_id===Number(t));if(r&&r.images&&r.images.length>0)return r.images;let o=await _.get(x.TEEPOD_IMAGES(t));return Lr.array(Re).parse(o)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}var Ct=new Nr().name("list").alias("ls").description("List available TEEPods").action(async()=>{try{let t=n.startSpinner("Fetching TEEPods"),e=await W();if(t.stop(!0),e.length===0){n.info("No TEEPods found");return}n.info("Available TEEPods:"),n.table(e,["teepod_id","name"])}catch(t){n.error(`Failed to list TEEPods: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Or}from"commander";import Ur from"inquirer";var wt=new Or().name("images").description("List available images for a TEEPod").option("-t, --teepod-id <teepodId>","TEEPod ID").action(async t=>{try{let e=n.startSpinner(`Fetching images for TEEPod ${t.teepodId}`);if(!t.teepodId){let o=n.startSpinner("Fetching available TEEPods"),i=await W();o.stop(!0),i.length===0&&(n.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:a}=await Ur.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){n.info(`No images found for TEEPod ${t.teepodId}`);return}n.info(`Available images for TEEPod ${t.teepodId}:`),n.table(r,["name","description"])}catch(e){n.error(`Failed to list images: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var kt=new zr().name("teepods").description("TEEPod management commands").addCommand(Ct).addCommand(wt);import{Command as oo}from"commander";import{Command as Yr}from"commander";import{execa as Tt}from"execa";import H from"fs";import Ue from"path";import Gr from"handlebars";import{exec as Kr,spawn as Hr}from"child_process";import{promisify as qr}from"util";import Zr from"os";import jr from"inquirer";import Ve from"fs";import Le from"path";function B(t,e=process.cwd()){let r=Le.resolve(e,t);if(!Ve.existsSync(r))throw new Error(`File not found at ${r}`);return!0}async function G(t,e,r="file",o=process.cwd()){return(await jr.prompt([{type:"input",name:r,message:t,default:e,validate:a=>{let c=Le.resolve(o,a);return Ve.existsSync(c)?!0:`File not found at ${c}`}}]))[r]}function ke(t,e){for(let r of t){let o=Le.join(process.cwd(),r);if(Ve.existsSync(o))return e?n.info(e.replace("{path}",o)):n.info(`File detected: ${o}`),r}}import*as I from"fs";import*as U from"path";import*as Q from"os";import{execSync as ee,spawn as Wr}from"child_process";import*as Ne from"net";var A={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:U.join(Q.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:U.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 St(){try{if(!I.existsSync(A.installDir))return!1;let t=Q.platform();if(!A.platforms[t])throw new Error(`Unsupported platform: ${t}`);let e=U.join(A.installDir,A.platforms[t].extractedFolder);if(!I.existsSync(e))return!1;let o=U.join(e,t==="win32"?"tappd-simulator.exe":"tappd-simulator");return I.existsSync(o)}catch(t){return n.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 Et(t){let e=r=>{n.info(r),t&&t(r)};try{let r=ue(),o=A.platforms[r];I.existsSync(A.installDir)||(n.info(`Creating installation directory at ${A.installDir}`),I.mkdirSync(A.installDir,{recursive:!0})),process.chdir(A.installDir);let i=`${A.baseUrl}/${o.filename}`;n.info(`Downloading simulator from ${i}`),ee(`wget ${i}`,{stdio:"inherit"}),n.info(`Extracting ${o.filename}`),ee(`tar -xvf ${o.filename}`,{stdio:"inherit"}),n.success("Simulator installation completed successfully")}catch(r){throw n.error("Error installing simulator:",r),new Error(`Failed to install simulator: ${r}`)}}async function xt(t={}){try{let e=ue(),r=A.platforms[e],o=U.join(A.installDir,r.extractedFolder);process.chdir(o);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 g=U.dirname(a.logFilePath);I.existsSync(g)||I.mkdirSync(g,{recursive:!0}),n.info(`Simulator logs will be written to: ${a.logFilePath}`)}n.info(`Starting simulator with: ${i} -l ${r.socketArg}`);let c="inherit",p=null;a.logToFile&&(p=I.createWriteStream(a.logFilePath,{flags:"a"}),c=["ignore",p,p]);let f=Wr(i,["-l",r.socketArg],{stdio:c,shell:e==="win32",detached:a.background});if(p){let g=new Date().toISOString();p.write(`
|
105
|
+
[${g}] Simulator started
|
106
|
+
`)}return a.background&&(f.unref(),n.success("Simulator is running in the background")),await Oe(),f}catch(e){throw n.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 I.existsSync(r)?new Promise(o=>{let i=Ne.createConnection({path:r}).on("connect",()=>{i.end(),o(!0)}).on("error",()=>{o(!1)});setTimeout(()=>{i.end(),o(!1)},1e3)}):!1}else if(t==="win32"){let r="127.0.0.1";return new Promise(i=>{let a=Ne.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 n.error("Error checking if simulator is running:",t),!1}}async function _t(){try{let t=ue();if(!await Se())return n.info("Simulator is not running"),!0;n.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?n.success("Simulator stopped successfully"):n.error("Failed to stop simulator"),await K(),e}catch(t){return n.error("Error stopping simulator:",t),!1}}function Br(){return ue()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function Oe(t){try{let e=Br(),r=t||e;return await ee(`export DSTACK_SIMULATOR_ENDPOINT=${r}`),n.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${r} for current process`),t}catch(e){throw n.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"),n.success("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var de=qr(Kr),$t=".phala-cloud/logs",Jr=".phala-cloud/compose",Pt=10,T=class{username;image;registry;constructor(e,r,o){this.image=e,this.username=r||"",this.registry=o||""}ensureLogsDir(){let e=Ue.resolve($t);H.existsSync(e)||H.mkdirSync(e,{recursive:!0})}getLogFilePath(e){let r=new Date().toISOString().replace(/[:.]/g,"-");return Ue.resolve($t,`${this.image}-${e}-${r}.log`)}getSystemArchitecture(){let e=Zr.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,r,o){return new Promise((i,a)=>{let c=Hr(e,r),p=this.getLogFilePath(o);this.ensureLogsDir();let f=H.createWriteStream(p,{flags:"a"}),g=[],v=(y,m=!1)=>{let l=y.toString().split(`
|
107
|
+
`);f.write(y),l.forEach(u=>{u.trim()&&(g.push(u),g.length>Pt&&g.shift(),console.clear(),console.log(`Latest ${Pt} lines (full log at ${p}):`),console.log("-".repeat(50)),g.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=>{f.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=>{f.end(),a(y)})})}setCredentials(e,r){this.username=e,r&&(this.registry=r)}async buildImage(e,r){try{let o=this.getSystemArchitecture(),i=`${this.username}/${this.image}:${r}`,a=n.startSpinner(`Building Docker image ${this.username}/${this.image}:${r}`);B(e);let c=["build","-t",i,"-f",e];return o==="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(o){return n.error(`Failed to build Docker image: ${o instanceof Error?o.message:String(o)}`),!1}}async pushImage(e){try{let r=n.startSpinner("Pushing Docker image to Docker Hub");if(!await N())throw r.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let i=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 n.error(`Failed to push Docker image: ${r instanceof Error?r.message:String(r)}`),!1}}async login(e,r,o){try{let i=n.startSpinner(`Logging in to Docker Hub as ${e}`);return await this.checkLogin()?(i.stop(!0,`Logged in as ${e}`),this.setCredentials(e,o),!0):(await Tt("docker",["login",...o?[o]:[],"-u",e,"--password-stdin"],{input:r}),i.stop(!0,"Logged in to Docker Hub successfully"),!0)}catch(i){return n.error(`Failed to login to Docker Hub: ${i instanceof Error?i.message:String(i)}`),!1}}async checkLogin(){try{let{stdout:e}=await Tt("docker",["login"]);return e.includes("Login Succeeded")}catch{return!1}}async buildComposeFile(e,r,o){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let i=o=="eliza"?nt:it,a=ct.parse({template:i}),c=Jr;H.existsSync(c)||(n.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 u=l.indexOf("#");return u>0&&(l=l.substring(0,u).trim()),l.trim()}).filter(l=>l.includes("=")).map(l=>{let[u,h]=l.split("=",2),b=u.trim();return(h?h.trim():"")===""?null:`${b}=${b}`}).filter(Boolean));let f=`${this.username}/${this.image}`,v=Gr.compile(a.template,{noEscape:!0})({imageName:f,tag:e,envVars:p.map(m=>m.replace(/=.*/,"=${"+m.split("=")[0]+"}"))}),y=Ue.join(c,`${this.image}-${e}-tee-compose.yaml`);return H.writeFileSync(y,v),n.success(`Backup of docker compose file created at: ${y}`),y}async runComposeLocally(e,r){try{let o=n.startSpinner(`Running Docker Compose file at ${e}`);B(e);let i=["-f",e,"up","-d"];return r&&(B(r),i.splice(2,0,"--env-file",r)),await de(`docker compose ${i.join(" ")}`),o.stop(!0,"Docker Compose file running successfully"),!0}catch(o){return n.error(`Failed to run Docker Compose file: ${o instanceof Error?o.message:String(o)}`),!1}}async runSimulator(e,r){try{n.info(`Running TEE simulator with image ${e}`),n.info("Pulling latest simulator image..."),await de(`docker pull ${e}`),n.info("Starting simulator in background...");let{stdout:o}=await de(`docker run -d --name tee-simulator --rm -p ${r}:${r} ${e}`),i=o.trim();return n.success(`TEE simulator running successfully. Container ID: ${i}`),n.info(`
|
111
110
|
|
112
|
-
Useful commands:`),
|
113
|
-
`),
|
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 <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=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){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("="),
|
116
|
-
`;if(
|
117
|
-
Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("0.0.1").addCommand(
|
111
|
+
Useful commands:`),n.info(`- View logs: docker logs -f ${i}`),n.info(`- Stop simulator: docker stop ${i}
|
112
|
+
`),Oe(`http://localhost:${r}`),!0}catch(o){return n.error(`Failed to run TEE simulator: ${o instanceof Error?o.message:String(o)}`),!1}}async stopSimulator(){try{let e=n.startSpinner("Stopping TEE simulator...");return await de("docker stop tee-simulator"),await K(),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return n.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}}"'),o=(await N())?.username;return e.split(`
|
113
|
+
`).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${o}/`)).map(a=>({imageName:a}))}catch(e){return n.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import Dt from"prompts";var At=new Yr().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,o=t.registry;if(!e){n.info("First we need your Docker Hub username to check if you are already logged in.");let p=await Dt({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:f=>f.length>0?!0:"Username cannot be empty"});p.username||(n.error("Username is required"),process.exit(1)),e=p.username}let i=new T("",e,o);if(await i.login(e)){n.success(`${e} is logged in to Docker Hub`);return}if(!r){let p=await Dt({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:f=>f.length>0?!0:"Password cannot be empty"});p.password||(n.error("Password is required"),process.exit(1)),r=p.password}await i.login(e,r,o)||(n.error("Failed to login to Docker Hub"),process.exit(1)),await Qe({username:e,registry:o||null}),n.success("Logged in to Docker Hub successfully")}catch(e){n.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Xr}from"commander";import It from"path";import Ft from"inquirer";import Qr from"fs";var Mt=new Xr().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 N();if(e||(n.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!t.image){let c=await Ft.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 Ft.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=It.resolve(process.cwd(),t.file);Qr.existsSync(r)||(n.info(`Default Dockerfile not found at ${r}`),t.file=await G("Enter the path to your Dockerfile:","Dockerfile","file"));let o=It.resolve(process.cwd(),t.file);await new T(t.image,e.username,e.registry).buildImage(o,t.tag)||(n.error("Failed to build Docker image"),process.exit(1)),n.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){n.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as eo}from"commander";import to from"inquirer";var Rt=new eo().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Full image name (e.g. username/image:tag)").action(async t=>{try{let e=await N();e||(n.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let r=t.image;if(!r){let o=await T.listLocalImages();if(o.length===0&&(n.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let c=Array.from(new Set(o.map(f=>f.imageName))),{selectedImage:p}=await to.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:c}]);r=p}await new T(r,e.username,e.registry).pushImage(r)||(n.error("Failed to push Docker image"),process.exit(1))}n.success(`Docker image ${r} pushed successfully`)}catch(e){n.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ro}from"commander";import M from"inquirer";import fe from"fs";import Ee from"path";var Vt=new ro().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 N();(!e||!e.username)&&(n.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let r=t.image||"",o=t.tag||"";if((!r||!o)&&!t.manual)try{n.info("Detecting local Docker images...");let f=await T.listLocalImages();if(f.length===0)n.warn("No local Docker images found. You will need to enter image details manually.");else{let g=new Map;if(f.forEach(v=>{g.has(v.name)||g.set(v.name,[]),g.get(v.name)?.push(v.tag)}),r&&!o){let v=g.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 ]"&&(o=y)}else n.warn(`No tags found for image ${r}. You will need to enter the tag manually.`)}else if(!r){let v=Array.from(g.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=g.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 ]"&&(o=l)}}}}catch(f){n.warn(`Failed to detect local images: ${f instanceof Error?f.message:String(f)}`),n.info("Continuing with manual input...")}if(!r){let{inputImage:f}=await M.prompt([{type:"input",name:"inputImage",message:"Enter Docker image name:",validate:g=>g.trim()?!0:"Image name cannot be empty"}]);r=f}if(!o){let{inputTag:f}=await M.prompt([{type:"input",name:"inputTag",message:`Enter tag for image ${r}:`,validate:g=>g.trim()?!0:"Tag cannot be empty"}]);o=f}let i=t.envFile;if(i)try{B(i)}catch{n.error(`File not found: ${i}`),process.exit(1)}else{let f=Ee.join(process.cwd(),".env");if(fe.existsSync(f)){let{useDefault:v}=await M.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);v&&(i=f)}if(!i){let{envPath:v}=await M.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:y=>{try{return B(y),!0}catch{return`File not found: ${y}`}}}]);i=v}}let a=t.output;if(!a&&(a=Ee.join(process.cwd(),"docker-compose.yml"),fe.existsSync(a))){let{confirmOverwrite:f}=await M.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${a} already exists. Overwrite?`,default:!1}]);if(!f){let{customPath:g}=await M.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:Ee.join(process.cwd(),"docker-generated-compose.yml")}]);a=g}}let c=new T(r,e.username,e.registry);i?n.info(`Generating Docker Compose file for ${r}:${o} using env file: ${i}`):n.info(`Generating Docker Compose file for ${r}:${o} without env file`);let p=await c.buildComposeFile(o,i,t.template);if(p!==a){let f=Ee.dirname(a);fe.existsSync(f)||(n.info(`Creating directory: ${f}`),fe.mkdirSync(f,{recursive:!0})),fe.copyFileSync(p,a)}n.success(`Docker Compose file generated successfully: ${a}`)}catch(e){n.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Lt=new oo().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(At).addCommand(Mt).addCommand(Rt).addCommand(Vt);import{Command as so}from"commander";import{Command as no}from"commander";var Nt=new no().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",tt).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 T("").runSimulator(t.image,t.port)||(n.error("Failed to start TEE simulator"),process.exit(1));else if(t.type==="native")if(St()||await Et(),await Se()){n.success("TEE simulator is already running");return}else{let r=xt();n.success("TEE simulator started successfully")}else n.error("Invalid simulator type"),process.exit(1)}catch(e){n.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as io}from"commander";var Ot=new io().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 T("").stopSimulator()||(n.error("Failed to stop TEE simulator"),process.exit(1)):t.type==="native"?await _t()||(n.error("Failed to stop TEE simulator"),process.exit(1)):(n.error("Invalid simulator type"),process.exit(1))}catch(e){n.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Ut=new so().name("simulator").description("TEE simulator commands").addCommand(Nt).addCommand(Ot);import{Command as xo}from"commander";import{Command as co}from"commander";import ao from"inquirer";import{z as zt}from"zod";async function xe(){try{let t=await _.get(x.CVMS(0));return zt.array(Me).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function $(t){let r=(await xe()).find(o=>o.hosted?.app_id===t||`app_${o.hosted?.app_id}`===t);if(!r)n.error(`CVM with App ID app_${t} not detected`),process.exit(1);else return n.success(`CVM with App ID app_${t} detected`),r.hosted?.app_id}async function te(t){try{let e=await _.get(x.CVM_BY_APP_ID(t));return pt.parse(e)}catch(e){throw new Error(`Failed to get CVM by App ID: ${e instanceof Error?e.message:String(e)}`)}}async function jt(t){try{let e=await _.post(x.CVM_PUBKEY,t);return lt.parse(e)}catch(e){throw new Error(`Failed to get pubkey from CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Wt(t){try{let e=await _.post(x.CVM_FROM_CONFIGURATION,t);return mt.parse(e)}catch(e){throw e instanceof zt.ZodError?(n.error("Schema validation error:",JSON.stringify(e.errors,null,2)),n.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 Bt(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 Gt(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 Kt(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 Ht(t,e){try{let r=await _.put(x.CVM_UPGRADE(t),e);return dt.parse(r)}catch(r){throw new Error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`)}}async function qt(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=n.startSpinner("Fetching available CVMs"),e=await xe();if(t.stop(!0),!e||e.length===0){n.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:o}=await ao.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:r}]);return o}async function Zt(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 Jt(t,e,r,o,i){try{let a={};if(e!==void 0&&(a.vcpu=e),r!==void 0&&(a.memory=r),o!==void 0&&(a.disk_size=o),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 ze from"chalk";var Yt=new co().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=n.startSpinner("Fetching CVMs"),r=await xe();if(e.stop(!0),!r||r.length===0){n.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(r,null,2));return}r.forEach(o=>{n.keyValueTable({"App ID":`app_${o.hosted.app_id}`,Name:o.name,Status:o.status==="running"?ze.green(o.status):o.status==="stopped"?ze.red(o.status):ze.yellow(o.status),"Node Info URL":o.hosted.app_url,"App URL":`${J}/dashboard/cvms/app_${o.hosted.app_id}`})}),n.success(`Found ${r.length} CVMs:`)}catch(e){n.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as mo}from"commander";import je from"chalk";var Xt=new mo().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);else if(t=await P(),!t){n.info("No CVMs found or selection cancelled");return}let r=n.startSpinner(`Fetching CVM with App ID app_${t}`),o=await te(t);if(r.stop(!0),o||(n.error(`CVM with App ID app_${t} not found`),process.exit(1)),e.json){console.log(JSON.stringify(o,null,2));return}n.keyValueTable({Name:o.name,"App ID":`app_${o.app_id}`,Status:o.status==="running"?je.green(o.status):o.status==="stopped"?je.red(o.status):je.yellow(o.status),vCPU:o.vcpu,Memory:`${o.memory} MB`,"Disk Size":`${o.disk_size} GB`,"Dstack Image":o.base_image,"App URL":`${J}/dashboard/cvms/app_${o.app_id}`})}catch(r){n.error(`Failed to get CVM details: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as lo}from"commander";var Qt=new lo().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);else if(t=await P(),!t)return;let e=n.startSpinner(`Starting CVM with App ID app_${t}`);await Bt(t),e.stop(!0),n.success(`CVM with App ID app_${t} started successfully`)}catch(e){n.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as po}from"commander";var er=new po().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);else if(t=await P(),!t)return;let e=n.startSpinner(`Stopping CVM with App ID app_${t}`);await Gt(t),e.stop(!0),n.success(`CVM with App ID app_${t} stopped successfully`)}catch(e){n.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as uo}from"commander";var tr=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 $(t);else if(t=await P(),!t)return;let e=n.startSpinner(`Restarting CVM with App ID app_${t}`);await Kt(t),e.stop(!0),n.success(`CVM with App ID app_${t} restarted successfully`)}catch(e){n.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as fo}from"commander";import _e from"chalk";var rr=new fo().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);else{n.info("No CVM specified, fetching available CVMs...");let o=await P();if(!o)return;t=o}n.info(`Fetching attestation information for CVM app_${t}...`);let r=n.startSpinner("Fetching attestation information");try{let o=await Zt(t);if(r.stop(!0),!o||Object.keys(o).length===0){n.info("No attestation information found");return}if(e?.json){n.info(JSON.stringify(o,null,2));return}n.success("Attestation Summary:");let i={Status:o.is_online?_e.green("Online"):_e.red("Offline"),"Public Access":o.is_public?_e.green("Enabled"):_e.yellow("Disabled"),Error:o.error||"None",Certificates:`${o.app_certificates?.length||0} found`};n.keyValueTable(i,{borderStyle:"rounded"}),o.app_certificates&&o.app_certificates.length>0&&o.app_certificates.forEach((a,c)=>{n.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};n.keyValueTable(p,{borderStyle:"single"})}),o.tcb_info&&(n.success("Trusted Computing Base (TCB) Information:"),n.keyValueTable(o.tcb_info,{borderStyle:"single"}))}catch(o){throw r.stop(!0),o}}catch(r){n.error(`Failed to get attestation information: ${r instanceof Error?r.message:String(r)}`)}});import{Command as ho}from"commander";import{encryptEnvVars as yo}from"@phala/dstack-sdk/encrypt-env-vars";import or from"fs";import vo from"path";import he from"inquirer";import go from"fs";var ge=(t,e)=>{let r={};if(t){for(let o of t)if(o.includes("=")){let[i,a]=o.split("=");i&&a&&(r[i]=a)}}if(e){let o=go.readFileSync(e,"utf8");for(let i of o.split(`
|
114
|
+
`))if(!(!i.trim()||i.trim().startsWith("#"))&&i.includes("=")){let[a,...c]=i.split("="),p=c.join("="),f=p.search(/\s+#/);f!==-1&&(p=p.substring(0,f).trim()),a&&p&&(r[a.trim()]=p.trim())}}return Object.entries(r).map(([o,i])=>({key:o,value:i}))};var nr=new ho().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",rt).option("--image <image>","Version of dstack image to use",ot).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=vo.resolve(t.compose);or.existsSync(e)||(n.error(`Docker Compose file not found: ${e}`),process.exit(1));let r=or.readFileSync(e,"utf8");await K();let o=[];if(t.envFile)try{o=ge([],t.envFile)}catch(m){n.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}]))n.info("Skipping environment variable prompt");else{let l=await G("Enter the path to your environment file:",".env","file");o=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=n.startSpinner("Fetching available TEEPods"),l=await W();m.stop(!0),l.length===0&&(n.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:u}=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===u);h||(n.error("Failed to find selected TEEPod"),process.exit(1)),n.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:u}=await he.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:l}]);t.image=u.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=n.startSpinner("Getting public key from CVM"),p=await jt(a);c.stop(!0),p||(n.error("Failed to get public key from CVM"),process.exit(1));let f=n.startSpinner("Encrypting environment variables"),g=await yo(o,p.app_env_encrypt_pubkey);f.stop(!0),t.debug&&(n.debug("Public key:",p.app_env_encrypt_pubkey),n.debug("Encrypted environment variables:",g),n.debug("Environment variables:",JSON.stringify(o)));let v=n.startSpinner("Creating CVM"),y=await Wt({...a,encrypted_env:g,app_env_encrypt_pubkey:p.app_env_encrypt_pubkey,app_id_salt:p.app_id_salt});v.stop(!0),y||(n.error("Failed to create CVM"),process.exit(1)),n.success("CVM created successfully"),n.info(`CVM ID: ${y.id}`),n.info(`Name: ${y.name}`),n.info(`Status: ${y.status}`),n.info(`App ID: ${y.app_id}`),y.app_url?n.info(`App URL: ${y.app_url}`):n.info(`App URL: ${J}/dashboard/cvms/app_${y.app_id}`),n.info(""),n.info("Your CVM is being created. You can check its status with:"),n.info(`phala cvms get ${y.app_id}`)}catch(e){n.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as bo}from"commander";import Co from"inquirer";var ir=new bo().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);else if(t=await P(),!t)return;if(!e.force){let{confirm:i}=await Co.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID app_${t}? This action cannot be undone.`,default:!1}]);if(!i){n.info("Deletion cancelled");return}}let r=n.startSpinner(`Deleting CVM app_${t}`),o=await qt(t);r.stop(!0),o||(n.error(`Failed to delete CVM app_${t}`),process.exit(1)),n.success(`CVM app_${t} deleted successfully`)}catch(r){n.error(`Failed to delete CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as wo}from"commander";import ko from"fs";import{encryptEnvVars as So}from"@phala/dstack-sdk/encrypt-env-vars";var sr=new wo().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);else{n.info("No CVM specified, fetching available CVMs...");let g=await P();if(!g)return;t=g}let r=n.startSpinner(`Fetching current configuration for CVM app_${t}`),o=await te(t);if(r.stop(!0),o||(n.error(`CVM with App ID app_${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=ko.readFileSync(e.compose,"utf8")}catch(g){n.error(`Failed to read Docker Compose file: ${g instanceof Error?g.message:String(g)}`),process.exit(1)}await K();let a="";if(e.envFile){let g=[];if(e.envFile)try{g=ge([],e.envFile),a=await So(g,o.encrypted_env_pubkey)}catch(v){n.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=n.startSpinner(`Upgrading CVM app_${t}`),f=await Ht(t,c);p.stop(!0),f||(n.error("Failed to upgrade CVM"),process.exit(1)),n.success(`CVM app_${t} upgraded successfully`),f.detail&&n.info(`Details: ${f.detail}`)}catch(r){n.error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Eo}from"commander";import ye from"inquirer";import z from"chalk";var ar=new Eo().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);else if(t=await P(),!t){n.info("No CVMs found or selection cancelled");return}let r=await te(t),o=e.vcpu,i=e.memory,a=e.diskSize,c=e.allowRestart;o||(o=(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 app_${t} with the following changes:
|
115
|
+
`;if(n.keyValueTable({vCPUs:r.vcpu!==o?`${z.red(r.vcpu)} -> ${z.green(o)}`:r.vcpu,Memory:r.memory!==i?`${z.red(r.memory)} MB -> ${z.green(i)} MB`:r.memory,"Disk Size":r.disk_size!==a?`${z.red(r.disk_size)} GB -> ${z.green(a)} GB`:r.disk_size,"Allow Restart":c?z.green("Yes"):z.red("No")}),!e.yes){let{confirm:v}=await ye.prompt([{type:"confirm",name:"confirm",message:p,default:!1}]);if(!v){n.info("Resize operation cancelled");return}}let f=n.startSpinner(`Resizing CVM with App ID app_${t}`);await Jt(t,o,i,a,c?1:0),f.stop(!0),n.success(`CVM with App ID app_${t} resized successfully`)}catch(r){n.error(`Failed to resize CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var cr=new xo().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(Yt).addCommand(Xt).addCommand(nr).addCommand(sr).addCommand(Qt).addCommand(er).addCommand(tr).addCommand(rr).addCommand(ir).addCommand(ar);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function To(){new _o().name("phala").description(`${He}
|
116
|
+
Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("0.0.1").addCommand(bt).addCommand(cr).addCommand(Lt).addCommand(Ut).addCommand(kt).parse(process.argv)}To().catch(t=>{n.error("An error occurred:",t),process.exit(1)});
|
118
117
|
//# sourceMappingURL=index.js.map
|