phala 1.0.1 → 1.0.2

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 CHANGED
@@ -63,7 +63,7 @@ ___
63
63
 
64
64
  To deploy applications to Phala Cloud, you'll need an API key:
65
65
 
66
- - Visit [Phala Cloud](https://cloud.phala.network/login) to log into your Phala Cloud account. If you do not have an account, register with this link with [PROMO_CODE](https://cloud.phala.network/register?invite=PHALACLI).
66
+ - Visit [Phala Cloud](https://cloud.phala.network/login) to log into your Phala Cloud account. If you do not have an account, register with this link with [PROMO_CODE](https://cloud.phala.network/register?invite=PHALACLI) or run `npx phala free` in the terminal.
67
67
  - After logging in, navigate to the "API Keys" section in your profile
68
68
  - Create a new API key with an appropriate name (e.g., "CLI Access")
69
69
  - Copy the generated API key - you'll need it for authentication
@@ -257,27 +257,6 @@ phala auth status
257
257
  phala auth status --json
258
258
  ```
259
259
 
260
- ### TEEPod Management Commands
261
-
262
- > WTF is TEEPod?
263
- > You can think of a TEEPod as the TEE server that the docker app with be hosted on. These TEEPods support published base images of the [Dstack Releases](https://github.com/Dstack-TEE/dstack/releases) which is the base image used to launch your Docker app. The Dstack base image is important as you can provide evidence to reproduce the RA Quote of your docker app deployment. More details on this later.
264
-
265
- Commands for managing TEEPods on Phala Cloud.
266
-
267
- #### List TEEPods
268
-
269
- ```bash
270
- phala teepods list
271
- ```
272
-
273
- List all available TEEPods on Phala Cloud.
274
-
275
- **Example:**
276
- ```bash
277
- phala teepods list
278
- ```
279
-
280
-
281
260
  ### Docker Management Commands
282
261
 
283
262
  Commands for managing Docker images for TEE deployments.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- var dr=Object.defineProperty;var fr=(t,e,o)=>e in t?dr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o;var Ze=(t,e,o)=>(fr(t,typeof e!="symbol"?e+"":e,o),o);import{Command as Io}from"commander";import Ye from"chalk";var Je=Ye.hex("#cdfa50"),Xe=Je(`
2
+ var yr=Object.defineProperty;var br=(t,e,o)=>e in t?yr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o;var Je=(t,e,o)=>(br(t,typeof e!="symbol"?e+"":e,o),o);import{Command as Vo}from"commander";import Xe from"chalk";var Qe=Xe.hex("#cdfa50"),Ce=Qe(`
3
3
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
4
4
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
5
5
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800
@@ -21,7 +21,7 @@ var dr=Object.defineProperty;var fr=(t,e,o)=>e in t?dr(t,e,{enumerable:!0,config
21
21
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800
22
22
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
23
23
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
24
- `),Fo=Je(`
24
+ `),Uo=Qe(`
25
25
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
26
26
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
27
27
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800
@@ -43,7 +43,7 @@ var dr=Object.defineProperty;var fr=(t,e,o)=>e in t?dr(t,e,{enumerable:!0,config
43
43
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800
44
44
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
45
45
  \u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
46
- `),Mo=Ye.cyan("PHALA TEE CLOUD CLI");import{Command as Or}from"commander";import{Command as Mr}from"commander";import M from"node:fs";import Re from"node:path";import Z from"node:os";import be from"node:crypto";import w from"chalk";function gr(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 H(t){return gr(t).length}function re(t,e){if(!t)return[""];if(H(t)<=e)return[t];let o=[],n="",s=0,a=t.split(/(\s+)/).filter(c=>c.trim().length>0);for(let c of a){let u=H(c);if(u>e){n&&(o.push(n),n="",s=0),o.push(c);continue}s+u+(s>0?1:0)>e?(o.push(n),n=c,s=u):n?(n=`${n} ${c}`,s+=u+1):(n=c,s=u)}return n&&o.push(n),o}var r={error:(t,...e)=>{console.error(w.red("\u2717"),w.red(t),...e)},warn:(t,...e)=>{console.log(w.yellow("\u26A0"),w.yellow(t),...e)},info:(t,...e)=>{console.log(w.blue("\u2139"),w.blue(t),...e)},success:(t,...e)=>{console.log(w.green("\u2713"),w.green(t),...e)},debug:(t,...e)=>{process.env.DEBUG&&console.log(w.gray("\u{1F50D}"),w.gray(t),...e)},table:(t,e)=>{if(t.length===0){console.log(w.yellow("No data to display"));return}if(e)if(typeof e[0]=="string"){let o=e.map(n=>({key:n,header:n.charAt(0).toUpperCase()+n.slice(1)}));De(t,{columns:o,borderStyle:"rounded",headerStyle:n=>w.cyan.bold(n)})}else De(t,{columns:e,borderStyle:"rounded",headerStyle:o=>w.cyan.bold(o)});else De(t,{borderStyle:"rounded",headerStyle:o=>w.cyan.bold(o)})},keyValueTable:(t,e)=>{let n={...{borderStyle:"rounded",enableTextWrapping:!0,maxDepth:2,formatKeys:!0,keyFormatter:_=>{let x=["URL","ID","API","UI","URI","CPU","GPU","RAM","JSON","XML","HTML","HTTP","HTTPS","SSH","FTP","IP","TCP","UDP","DNS","SSL","TLS","SQL","VCPU","CVM","TEE","IO"],P={teepod:"TEEPod",dstack:"Dstack"},F;_.includes("_")?F=_.split("_").map(R=>R.charAt(0).toUpperCase()+R.slice(1).toLowerCase()).join(" "):_.includes("-")?F=_.split("-").map(R=>R.charAt(0).toUpperCase()+R.slice(1).toLowerCase()).join(" "):F=_.charAt(0).toUpperCase()+_.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let R of x){let N=new RegExp(`\\b${R.toLowerCase()}\\b`,"gi");F=F.replace(N,R)}for(let[R,N]of Object.entries(P)){let ve=new RegExp(`\\b${R}\\b`,"gi");F=F.replace(ve,N)}return F},valueFormatter:_=>String(_??"")},...e},{include:s,exclude:a,keyFormatter:c,valueFormatter:u,formatKeys:h,keyWidth:f,valueWidth:C,borderStyle:v,enableTextWrapping:p,maxDepth:m}=n,l=Object.keys(t);if(s&&(l=l.filter(_=>s.includes(_))),a&&(l=l.filter(_=>!a.includes(_))),l.length===0){console.log(w.yellow("No properties to display"));return}let g=l.map(_=>{let x=t[_],P;return x==null?P="":typeof x=="object"&&!Array.isArray(x)?P=Qe(x,0,m):Array.isArray(x)?x.length===0?P="[]":typeof x[0]=="object"?P=`[${x.length} items]`:P=`[${x.join(", ")}]`:P=String(x),u&&(P=u(x,_)),{key:h&&c?w.cyan.bold(c(_)):w.cyan.bold(_),value:P}}),y=et(),d=f,b=C;if(d||(d=Math.max(...g.map(_=>H(_.key)),10),d=Math.min(d,Math.floor(y/3))),!b){b=Math.max(...g.map(P=>H(P.value)),10),b+=3;let _=7,x=y-d-_;b=Math.min(b,x)}let k=hr(v),z=`${k.topLeft}${k.horizontal.repeat(d+2)}${k.topT}${k.horizontal.repeat(b+2)}${k.topRight}`,V=`${k.leftT}${k.horizontal.repeat(d+2)}${k.cross}${k.horizontal.repeat(b+2)}${k.rightT}`;console.log(z),console.log(V),g.forEach((_,x)=>{let P=p?re(_.key,d):[_.key],F=p?re(_.value,b):[_.value],R=Math.max(P.length,F.length);for(let N=0;N<R;N++){let ve=P[N]||"",He=F[N]||"",lr=ve+" ".repeat(Math.max(0,d-H(ve))),ur=He+" ".repeat(Math.max(0,b-H(He)));console.log(`${k.vertical} ${lr} ${k.vertical} ${ur} ${k.vertical}`)}x<g.length-1&&console.log(`${k.leftT}${k.horizontal.repeat(d+2)}${k.cross}${k.horizontal.repeat(b+2)}${k.rightT}`)});let Ie=`${k.bottomLeft}${k.horizontal.repeat(d+2)}${k.bottomT}${k.horizontal.repeat(b+2)}${k.bottomRight}`;console.log(Ie)},startSpinner:t=>(process.stdout.write(`${w.blue("\u27F3")} ${t}... `),{stop:(e=!0,o)=>{let n=e?w.green("\u2713"):w.red("\u2717"),s=o?`: ${o}`:"";console.log(`${n}${s}`)}}),break(){console.log("")}};function Qe(t,e,o){if(e>=o)return"[Nested Object]";if(t==null)return"";if(Array.isArray(t))return t.length===0?"[]":`[${t.length} items]`;let n=[];for(let[s,a]of Object.entries(t))a==null?n.push(`${s}: `):typeof a=="object"?n.push(`${s}: ${Qe(a,e+1,o)}`):n.push(`${s}: ${a}`);return n.join(", ")}function hr(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 et(){return process.stdout.columns||80}function yr(t,e,o={}){let n=et(),s=o.borderChars??3,c=(o.additionalBorderWidth??1)+e.length*s,u=n-c,h={},f=0,C=0;for(let m of e){let l=m.key;if(m.fixedWidth!==void 0){h[l]=m.fixedWidth,f+=m.fixedWidth;continue}let g=m.minWidth??m.header.length,y;m.getWidth?y=Math.max(g,m.header.length,...t.map(d=>m.getWidth(d))):m.getValue?y=Math.max(g,m.header.length,...t.map(d=>String(m.getValue(d)||"").length)):y=Math.max(g,m.header.length,...t.map(d=>String(d[m.key]||"").length)),h[l]=y,f+=y,C+=m.weight??1}let v=Math.max(0,u-f);if(v>0&&C>0)for(let m of e){let l=m.key;if(m.fixedWidth===void 0&&m.weight){let g=Math.floor(v*(m.weight/C));h[l]+=g}}let p=Object.values(h).reduce((m,l)=>m+l,0)+c;if(p>n){let m=u/(p-c),l={};for(let g of e){let y=g.key,d=g.minWidth??g.header.length;l[y]=Math.max(d,Math.floor(h[y]*m))}return l}return h}function De(t,e={}){if(e.keyValueMode&&t.length===1){let p=t[0],m=[];e.columns||(e.columns=Object.keys(p).map(l=>({key:l,header:l.charAt(0).toUpperCase()+l.slice(1).replace(/([A-Z])/g," $1")})));for(let l of e.columns){let g=String(l.key),y;if(l.accessor)y=l.accessor(p);else if(typeof l.key=="string"&&l.key.includes(".")){let d=l.key.split("."),b=p;for(let k of d){if(b==null){y="";break}b=b[k]}y=b}else y=p[l.key];l.formatter&&(y=l.formatter(y)),m.push({key:l.header||g,value:y})}t=m,e.columns=[{key:"key",minWidth:15},{key:"value",minWidth:20}]}if(t.length===0){console.log(w.yellow("No data to display"));return}let n={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:p=>w.bold(p),cellStyle:p=>p,enableTextWrapping:!0},...e},s=n.columns;if(s)s=s.map(p=>({...p,enableTextWrapping:p.enableTextWrapping!==void 0?p.enableTextWrapping:n.enableTextWrapping}));else{let p=t[0];s=Object.keys(p).map(m=>({key:m,header:m.charAt(0).toUpperCase()+m.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],u=s.map(p=>({key:p.key,header:p.header||String(p.key),minWidth:p.minWidth||3,weight:p.weight,enableTextWrapping:p.enableTextWrapping,getValue:p.accessor?m=>p.accessor(m):m=>{if(typeof p.key=="string"&&p.key.includes(".")){let l=p.key.split("."),g=m;for(let y of l){if(g==null)return"";g=g[y]}return g??""}return m[p.key]??""}})),h=yr(t,u),f=s.map((p,m)=>({...p,width:h[u[m].key]})),C=f.map(p=>p.header||String(p.key)),v=(p,m)=>{let l=f.map(d=>{let b;if(d.accessor)b=d.accessor(p);else if(typeof d.key=="string"&&d.key.includes(".")){let z=d.key.split("."),V=p;for(let Ie of z){if(V==null){b="";break}V=V[Ie]}b=V??""}else b=p[d.key]??"";let k=d.formatter?d.formatter(b):String(b||"");return d.enableTextWrapping?{lines:re(k,d.width),key:String(d.key)}:{lines:[k.length>d.width?k.substring(0,d.width-1)+"\u2026":k],key:String(d.key)}}),g=Math.max(...l.map(d=>d.lines.length)),y=[];for(let d=0;d<g;d++){let b=l.map((k,z)=>{let V=k.lines[d]||"";return n.cellStyle(V.padEnd(f[z].width),m,k.key)});y.push(b)}return y};if(n.border){let p=c.topLeft+f.map(l=>c.horizontal.repeat(l.width+2)).join(c.topT)+c.topRight;if(console.log(p),n.includeHeaders){let l=f.map((d,b)=>({lines:d.enableTextWrapping?re(C[b],d.width):[C[b]],width:d.width})),g=Math.max(...l.map(d=>d.lines.length));for(let d=0;d<g;d++){let b=c.vertical+l.map(k=>{let z=k.lines[d]||"";return" "+n.headerStyle(z.padEnd(k.width))+" "}).join(c.vertical)+c.vertical;console.log(b)}let y=c.leftT+f.map(d=>c.horizontal.repeat(d.width+2)).join(c.cross)+c.rightT;console.log(y)}t.forEach((l,g)=>{let y=v(l,g);if(y.forEach(d=>{console.log(c.vertical+d.map(b=>` ${b} `).join(c.vertical)+c.vertical)}),g<t.length-1&&y.length>1){let d=c.leftT+f.map(b=>c.horizontal.repeat(b.width+2)).join(c.cross)+c.rightT;console.log(d)}});let m=c.bottomLeft+f.map(l=>c.horizontal.repeat(l.width+2)).join(c.bottomT)+c.bottomRight;console.log(m)}else{if(n.includeHeaders){let p=f.map((g,y)=>({lines:g.enableTextWrapping?re(C[y],g.width):[C[y]],width:g.width})),m=Math.max(...p.map(g=>g.lines.length));for(let g=0;g<m;g++){let y=p.map(d=>{let b=d.lines[g]||"";return n.headerStyle(b.padEnd(d.width))}).join(" ");console.log(y)}let l=f.map(g=>"\u2500".repeat(g.width)).join(" ");console.log(l)}t.forEach((p,m)=>{let l=v(p,m);l.forEach(g=>{console.log(g.join(" "))}),m<t.length-1&&l.length>1&&console.log("")})}console.log(`Total: ${t.length} rows`)}var oe=Re.join(Z.homedir(),".phala-cloud"),ne=Re.join(oe,"api-key"),Ae=Re.join(oe,"docker-credentials.json");function tt(){if(!M.existsSync(oe))try{M.mkdirSync(oe,{recursive:!0})}catch(t){throw r.error(`Failed to create directory ${oe}:`,t),t}}function rt(){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 vr(t){try{let e=rt(),o=be.randomBytes(16),n=be.createCipheriv("aes-256-cbc",e.slice(0,32),o),s=n.update(t,"utf8","hex");return s+=n.final("hex"),o.toString("hex")+":"+s}catch(e){throw r.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function br(t){try{let e=rt(),o=t.split(":");if(o.length!==2)throw new Error("Invalid encrypted format");let n=Buffer.from(o[0],"hex"),s=o[1],a=be.createDecipheriv("aes-256-cbc",e.slice(0,32),n),c=a.update(s,"hex","utf8");return c+=a.final("utf8"),c}catch(e){throw r.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function Fe(t){tt();try{let e=vr(t);M.writeFileSync(ne,e,{mode:384})}catch(e){throw r.error("Failed to save API key:",e),e}}async function Y(){try{if(M.existsSync(ne)){let t=M.readFileSync(ne,"utf8").trim();return br(t)}return null}catch(t){return r.error("Failed to read API key:",t),null}}async function se(){try{M.existsSync(ne)?(M.unlinkSync(ne),r.success("API key removed successfully.")):r.warn("No API key found to remove.")}catch(t){throw r.error("Failed to remove API key:",t),t}}async function ot(t){tt();try{M.writeFileSync(Ae,JSON.stringify(t,null,2),{mode:384}),r.success("Docker information saved successfully.")}catch(e){throw r.error("Failed to save Docker information:",e),e}}async function L(){try{if(M.existsSync(Ae)){let t=M.readFileSync(Ae,"utf8");return JSON.parse(t)}return null}catch(t){return r.error("Failed to read Docker credentials:",t),null}}import Vr from"prompts";import Cr from"axios";var Me=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",S=process.env.CLOUD_URL||"https://cloud.phala.network",nt="0.0.1";var st="phalanetwork/tappd-simulator:latest",ie=2,ae=4096,ce=40,it="3",Ce="dstack-0.3.5",E={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_NETWORK:t=>`/api/v1/cvms/app_${t}/network`,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`},at=`version: '3.8'
46
+ `),zo=Xe.cyan("PHALA TEE CLOUD CLI");import{Command as Br}from"commander";import{Command as Or}from"commander";import M from"node:fs";import Me from"node:path";import Z from"node:os";import ke from"node:crypto";import _ from"chalk";function vr(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 vr(t).length}function re(t,e){if(!t)return[""];if(q(t)<=e)return[t];let o=[],n="",s=0,a=t.split(/(\s+)/).filter(c=>c.trim().length>0);for(let c of a){let u=q(c);if(u>e){n&&(o.push(n),n="",s=0),o.push(c);continue}s+u+(s>0?1:0)>e?(o.push(n),n=c,s=u):n?(n=`${n} ${c}`,s+=u+1):(n=c,s=u)}return n&&o.push(n),o}var r={error:(t,...e)=>{console.error(_.red("\u2717"),_.red(t),...e)},warn:(t,...e)=>{console.log(_.yellow("\u26A0"),_.yellow(t),...e)},info:(t,...e)=>{console.log(_.blue("\u2139"),_.blue(t),...e)},success:(t,...e)=>{console.log(_.green("\u2713"),_.green(t),...e)},debug:(t,...e)=>{process.env.DEBUG&&console.log(_.gray("\u{1F50D}"),_.gray(t),...e)},table:(t,e)=>{if(t.length===0){console.log(_.yellow("No data to display"));return}if(e)if(typeof e[0]=="string"){let o=e.map(n=>({key:n,header:n.charAt(0).toUpperCase()+n.slice(1)}));Re(t,{columns:o,borderStyle:"rounded",headerStyle:n=>_.cyan.bold(n)})}else Re(t,{columns:e,borderStyle:"rounded",headerStyle:o=>_.cyan.bold(o)});else Re(t,{borderStyle:"rounded",headerStyle:o=>_.cyan.bold(o)})},keyValueTable:(t,e)=>{let n={...{borderStyle:"rounded",enableTextWrapping:!0,maxDepth:2,formatKeys:!0,keyFormatter:w=>{let x=["URL","ID","API","UI","URI","CPU","GPU","RAM","JSON","XML","HTML","HTTP","HTTPS","SSH","FTP","IP","TCP","UDP","DNS","SSL","TLS","SQL","VCPU","CVM","TEE","IO"],P={teepod:"TEEPod",dstack:"Dstack"},F;w.includes("_")?F=w.split("_").map(R=>R.charAt(0).toUpperCase()+R.slice(1).toLowerCase()).join(" "):w.includes("-")?F=w.split("-").map(R=>R.charAt(0).toUpperCase()+R.slice(1).toLowerCase()).join(" "):F=w.charAt(0).toUpperCase()+w.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let R of x){let N=new RegExp(`\\b${R.toLowerCase()}\\b`,"gi");F=F.replace(N,R)}for(let[R,N]of Object.entries(P)){let ve=new RegExp(`\\b${R}\\b`,"gi");F=F.replace(ve,N)}return F},valueFormatter:w=>String(w??"")},...e},{include:s,exclude:a,keyFormatter:c,valueFormatter:u,formatKeys:h,keyWidth:f,valueWidth:C,borderStyle:b,enableTextWrapping:p,maxDepth:m}=n,l=Object.keys(t);if(s&&(l=l.filter(w=>s.includes(w))),a&&(l=l.filter(w=>!a.includes(w))),l.length===0){console.log(_.yellow("No properties to display"));return}let g=l.map(w=>{let x=t[w],P;return x==null?P="":typeof x=="object"&&!Array.isArray(x)?P=et(x,0,m):Array.isArray(x)?x.length===0?P="[]":typeof x[0]=="object"?P=`[${x.length} items]`:P=`[${x.join(", ")}]`:P=String(x),u&&(P=u(x,w)),{key:h&&c?_.cyan.bold(c(w)):_.cyan.bold(w),value:P}}),y=tt(),d=f,v=C;if(d||(d=Math.max(...g.map(w=>q(w.key)),10),d=Math.min(d,Math.floor(y/3))),!v){v=Math.max(...g.map(P=>q(P.value)),10),v+=3;let w=7,x=y-d-w;v=Math.min(v,x)}let k=Cr(b),z=`${k.topLeft}${k.horizontal.repeat(d+2)}${k.topT}${k.horizontal.repeat(v+2)}${k.topRight}`,V=`${k.leftT}${k.horizontal.repeat(d+2)}${k.cross}${k.horizontal.repeat(v+2)}${k.rightT}`;console.log(z),console.log(V),g.forEach((w,x)=>{let P=p?re(w.key,d):[w.key],F=p?re(w.value,v):[w.value],R=Math.max(P.length,F.length);for(let N=0;N<R;N++){let ve=P[N]||"",Ye=F[N]||"",gr=ve+" ".repeat(Math.max(0,d-q(ve))),hr=Ye+" ".repeat(Math.max(0,v-q(Ye)));console.log(`${k.vertical} ${gr} ${k.vertical} ${hr} ${k.vertical}`)}x<g.length-1&&console.log(`${k.leftT}${k.horizontal.repeat(d+2)}${k.cross}${k.horizontal.repeat(v+2)}${k.rightT}`)});let Ae=`${k.bottomLeft}${k.horizontal.repeat(d+2)}${k.bottomT}${k.horizontal.repeat(v+2)}${k.bottomRight}`;console.log(Ae)},startSpinner:t=>(process.stdout.write(`${_.blue("\u27F3")} ${t}... `),{stop:(e=!0,o)=>{let n=e?_.green("\u2713"):_.red("\u2717"),s=o?`: ${o}`:"";console.log(`${n}${s}`)}}),break(){console.log("")}};function et(t,e,o){if(e>=o)return"[Nested Object]";if(t==null)return"";if(Array.isArray(t))return t.length===0?"[]":`[${t.length} items]`;let n=[];for(let[s,a]of Object.entries(t))a==null?n.push(`${s}: `):typeof a=="object"?n.push(`${s}: ${et(a,e+1,o)}`):n.push(`${s}: ${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 tt(){return process.stdout.columns||80}function kr(t,e,o={}){let n=tt(),s=o.borderChars??3,c=(o.additionalBorderWidth??1)+e.length*s,u=n-c,h={},f=0,C=0;for(let m of e){let l=m.key;if(m.fixedWidth!==void 0){h[l]=m.fixedWidth,f+=m.fixedWidth;continue}let g=m.minWidth??m.header.length,y;m.getWidth?y=Math.max(g,m.header.length,...t.map(d=>m.getWidth(d))):m.getValue?y=Math.max(g,m.header.length,...t.map(d=>String(m.getValue(d)||"").length)):y=Math.max(g,m.header.length,...t.map(d=>String(d[m.key]||"").length)),h[l]=y,f+=y,C+=m.weight??1}let b=Math.max(0,u-f);if(b>0&&C>0)for(let m of e){let l=m.key;if(m.fixedWidth===void 0&&m.weight){let g=Math.floor(b*(m.weight/C));h[l]+=g}}let p=Object.values(h).reduce((m,l)=>m+l,0)+c;if(p>n){let m=u/(p-c),l={};for(let g of e){let y=g.key,d=g.minWidth??g.header.length;l[y]=Math.max(d,Math.floor(h[y]*m))}return l}return h}function Re(t,e={}){if(e.keyValueMode&&t.length===1){let p=t[0],m=[];e.columns||(e.columns=Object.keys(p).map(l=>({key:l,header:l.charAt(0).toUpperCase()+l.slice(1).replace(/([A-Z])/g," $1")})));for(let l of e.columns){let g=String(l.key),y;if(l.accessor)y=l.accessor(p);else if(typeof l.key=="string"&&l.key.includes(".")){let d=l.key.split("."),v=p;for(let k of d){if(v==null){y="";break}v=v[k]}y=v}else y=p[l.key];l.formatter&&(y=l.formatter(y)),m.push({key:l.header||g,value:y})}t=m,e.columns=[{key:"key",minWidth:15},{key:"value",minWidth:20}]}if(t.length===0){console.log(_.yellow("No data to display"));return}let n={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:p=>_.bold(p),cellStyle:p=>p,enableTextWrapping:!0},...e},s=n.columns;if(s)s=s.map(p=>({...p,enableTextWrapping:p.enableTextWrapping!==void 0?p.enableTextWrapping:n.enableTextWrapping}));else{let p=t[0];s=Object.keys(p).map(m=>({key:m,header:m.charAt(0).toUpperCase()+m.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],u=s.map(p=>({key:p.key,header:p.header||String(p.key),minWidth:p.minWidth||3,weight:p.weight,enableTextWrapping:p.enableTextWrapping,getValue:p.accessor?m=>p.accessor(m):m=>{if(typeof p.key=="string"&&p.key.includes(".")){let l=p.key.split("."),g=m;for(let y of l){if(g==null)return"";g=g[y]}return g??""}return m[p.key]??""}})),h=kr(t,u),f=s.map((p,m)=>({...p,width:h[u[m].key]})),C=f.map(p=>p.header||String(p.key)),b=(p,m)=>{let l=f.map(d=>{let v;if(d.accessor)v=d.accessor(p);else if(typeof d.key=="string"&&d.key.includes(".")){let z=d.key.split("."),V=p;for(let Ae of z){if(V==null){v="";break}V=V[Ae]}v=V??""}else v=p[d.key]??"";let k=d.formatter?d.formatter(v):String(v||"");return d.enableTextWrapping?{lines:re(k,d.width),key:String(d.key)}:{lines:[k.length>d.width?k.substring(0,d.width-1)+"\u2026":k],key:String(d.key)}}),g=Math.max(...l.map(d=>d.lines.length)),y=[];for(let d=0;d<g;d++){let v=l.map((k,z)=>{let V=k.lines[d]||"";return n.cellStyle(V.padEnd(f[z].width),m,k.key)});y.push(v)}return y};if(n.border){let p=c.topLeft+f.map(l=>c.horizontal.repeat(l.width+2)).join(c.topT)+c.topRight;if(console.log(p),n.includeHeaders){let l=f.map((d,v)=>({lines:d.enableTextWrapping?re(C[v],d.width):[C[v]],width:d.width})),g=Math.max(...l.map(d=>d.lines.length));for(let d=0;d<g;d++){let v=c.vertical+l.map(k=>{let z=k.lines[d]||"";return" "+n.headerStyle(z.padEnd(k.width))+" "}).join(c.vertical)+c.vertical;console.log(v)}let y=c.leftT+f.map(d=>c.horizontal.repeat(d.width+2)).join(c.cross)+c.rightT;console.log(y)}t.forEach((l,g)=>{let y=b(l,g);if(y.forEach(d=>{console.log(c.vertical+d.map(v=>` ${v} `).join(c.vertical)+c.vertical)}),g<t.length-1&&y.length>1){let d=c.leftT+f.map(v=>c.horizontal.repeat(v.width+2)).join(c.cross)+c.rightT;console.log(d)}});let m=c.bottomLeft+f.map(l=>c.horizontal.repeat(l.width+2)).join(c.bottomT)+c.bottomRight;console.log(m)}else{if(n.includeHeaders){let p=f.map((g,y)=>({lines:g.enableTextWrapping?re(C[y],g.width):[C[y]],width:g.width})),m=Math.max(...p.map(g=>g.lines.length));for(let g=0;g<m;g++){let y=p.map(d=>{let v=d.lines[g]||"";return n.headerStyle(v.padEnd(d.width))}).join(" ");console.log(y)}let l=f.map(g=>"\u2500".repeat(g.width)).join(" ");console.log(l)}t.forEach((p,m)=>{let l=b(p,m);l.forEach(g=>{console.log(g.join(" "))}),m<t.length-1&&l.length>1&&console.log("")})}console.log(`Total: ${t.length} rows`)}var oe=Me.join(Z.homedir(),".phala-cloud"),ne=Me.join(oe,"api-key"),Fe=Me.join(oe,"docker-credentials.json");function rt(){if(!M.existsSync(oe))try{M.mkdirSync(oe,{recursive:!0})}catch(t){throw r.error(`Failed to create directory ${oe}:`,t),t}}function ot(){let t=[Z.hostname(),Z.platform(),Z.arch(),Z.cpus()[0]?.model||"",Z.userInfo().username],e=ke.createHash("sha256");return e.update(t.join("|")),e.digest()}function wr(t){try{let e=ot(),o=ke.randomBytes(16),n=ke.createCipheriv("aes-256-cbc",e.slice(0,32),o),s=n.update(t,"utf8","hex");return s+=n.final("hex"),o.toString("hex")+":"+s}catch(e){throw r.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function _r(t){try{let e=ot(),o=t.split(":");if(o.length!==2)throw new Error("Invalid encrypted format");let n=Buffer.from(o[0],"hex"),s=o[1],a=ke.createDecipheriv("aes-256-cbc",e.slice(0,32),n),c=a.update(s,"hex","utf8");return c+=a.final("utf8"),c}catch(e){throw r.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function Ve(t){rt();try{let e=wr(t);M.writeFileSync(ne,e,{mode:384})}catch(e){throw r.error("Failed to save API key:",e),e}}async function Y(){try{if(M.existsSync(ne)){let t=M.readFileSync(ne,"utf8").trim();return _r(t)}return null}catch(t){return r.error("Failed to read API key:",t),null}}async function se(){try{M.existsSync(ne)?(M.unlinkSync(ne),r.success("API key removed successfully.")):r.warn("No API key found to remove.")}catch(t){throw r.error("Failed to remove API key:",t),t}}async function nt(t){rt();try{M.writeFileSync(Fe,JSON.stringify(t,null,2),{mode:384}),r.success("Docker information saved successfully.")}catch(e){throw r.error("Failed to save Docker information:",e),e}}async function L(){try{if(M.existsSync(Fe)){let t=M.readFileSync(Fe,"utf8");return JSON.parse(t)}return null}catch(t){return r.error("Failed to read Docker credentials:",t),null}}import Ur from"prompts";import Sr from"axios";var Le=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",S=process.env.CLOUD_URL||"https://cloud.phala.network",st="0.0.1";var it="phalanetwork/tappd-simulator:latest",ie=2,ae=4096,ce=40,at="3",we="dstack-0.3.5",E={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_NETWORK:t=>`/api/v1/cvms/app_${t}/network`,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`},ct=`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:`,ct=`version: '3.8'
91
+ postgres-data:`,mt=`version: '3.8'
92
92
  services:
93
93
  app:
94
94
  image: {{imageName}}
@@ -99,21 +99,21 @@ services:
99
99
  {{#each envVars}} - {{{this}}}
100
100
  {{/each}}
101
101
  restart: always
102
- `;function Ve(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var Le=class{client;apiKey=null;constructor(e){r.debug(`Creating API client with base URL: ${e}`),this.client=Cr.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${nt}`}}),this.client.interceptors.request.use(async o=>{if(!this.apiKey){if(this.apiKey=await Y(),!this.apiKey)throw new Error('API key not found. Please set an API key first with "phala auth login"');r.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return o.headers["X-API-Key"]=this.apiKey,r.debug(`Making request to: ${o.baseURL}${o.url}`),o}),this.client.interceptors.response.use(o=>(r.debug(`Received successful response from: ${o.config.url}`),o),o=>{if(o.response){let{status:n,data:s}=o.response;r.debug(`Received error response: ${n} - ${Ve(s)}`),n===401?r.error("Authentication failed. Please check your API key."):n===403?r.error("You do not have permission to perform this action."):n===404?r.error("Resource not found."):r.error(`API Error (${n}): ${s.message||Ve(s)}`)}else o.request?(r.error("No response received from the server. Please check your internet connection."),r.debug(`Request details: ${Ve(o.request).substring(0,200)}...`)):r.error(`Error: ${o.message}`);return Promise.reject(o)})}async get(e,o){try{return r.debug(`GET request to: ${e}`),(await this.client.get(e,o)).data}catch(n){throw r.debug(`GET request failed: ${n instanceof Error?n.message:String(n)}`),n}}async post(e,o,n){try{return r.debug(`POST request to: ${e}`),(await this.client.post(e,o,n)).data}catch(s){throw r.debug(`POST request failed: ${s instanceof Error?s.message:String(s)}`),s}}async put(e,o,n){try{return r.debug(`PUT request to: ${e}`),(await this.client.put(e,o,n)).data}catch(s){throw r.debug(`PUT request failed: ${s instanceof Error?s.message:String(s)}`),s}}async delete(e,o){try{return r.debug(`DELETE request to: ${e}`),(await this.client.delete(e,o)).data}catch(n){throw r.debug(`DELETE request failed: ${n instanceof Error?n.message:String(n)}`),n}}async patch(e,o,n){try{return r.debug(`PATCH request to: ${e}`),(await this.client.patch(e,o,n)).data}catch(s){throw r.debug(`PATCH request failed: ${s instanceof Error?s.message:String(s)}`),s}}};r.debug(`Initializing API client with URL: ${Me}`);var T=new Le(Me);import{z as i}from"zod";import{INVALID as kr,ParseStatus as _r,ZodIssueCode as J,ZodParsedType as mt,ZodType as wr,addIssueToContext as X,z as pt}from"zod";var Sr="ZodDecimal",xr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,pe=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)!==mt.number){let a=this._getOrReturnCtx(e);return X(a,{code:J.invalid_type,expected:mt.number,received:a.parsedType}),kr}let n,s=new _r;for(let a of this._def.checks)if(a.kind==="precision"){let c=e.data.toString().match(xr);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:J.custom,message:a.message,params:{precision:a.value}}),s.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.custom,message:a.message,params:{wholeNumber:a.value}}),s.dirty()):a.kind==="min"?(a.inclusive?e.data<a.value:e.data<=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.too_small,minimum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),s.dirty()):a.kind==="max"?(a.inclusive?e.data>a.value:e.data>=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),s.dirty()):a.kind==="finite"&&(Number.isFinite(e.data)||(n=this._getOrReturnCtx(e,n),X(n,{code:J.not_finite,message:a.message}),s.dirty()));return{status:s.value,value:e.data}}setLimit(e,o,n,s){return new pe({...this._def,checks:[...this._def.checks,{kind:e,value:o,inclusive:n,message:s}]})}_addCheck(e){return new pe({...this._def,checks:[...this._def.checks,e]})}lte(e,o){return this.setLimit("max",e,!0,o)}lt(e,o){return this.setLimit("max",e,!1,o)}max=this.lte;gt(e,o){return this.setLimit("min",e,!1,o)}gte(e,o){return this.setLimit("min",e,!0,o)}min=this.gte;precision(e,o){return this._addCheck({kind:"precision",value:e,message:o})}wholeNumber(e,o){return this._addCheck({kind:"wholeNumber",value:e,message:o})}get minValue(){let e=null;for(let o of this._def.checks)o.kind==="min"&&(e===null||o.value>e)&&(e=o.value);return e}get maxValue(){let e=null;for(let o of this._def.checks)o.kind==="max"&&(e===null||o.value<e)&&(e=o.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,o=null;for(let n of this._def.checks){if(n.kind==="finite")return!0;n.kind==="min"?(o===null||n.value>o)&&(o=n.value):n.kind==="max"&&(e===null||n.value<e)&&(e=n.value)}return Number.isFinite(o)&&Number.isFinite(e)}},me=pe;Ze(me,"create",e=>new pe({checks:[],typeName:Sr,coerce:e?.coerce??!1}));var lt=pt.object({template:pt.string().min(1,"Template cannot be empty")});var Er=i.object({password:i.string(),registry:i.string().nullable(),username:i.string()}),Tr=i.object({docker_compose_file:i.string(),docker_config:Er.optional(),features:i.array(i.string()),kms_enabled:i.boolean(),manifest_version:i.number(),name:i.string(),public_logs:i.boolean(),public_sysinfo:i.boolean(),runner:i.string().optional(),salt:i.string().nullable().optional(),tproxy_enabled:i.boolean(),version:i.string().optional()}),$r=i.object({name:i.string(),image:i.string(),compose_file:Tr,vcpu:i.number(),memory:i.number(),disk_size:i.number(),ports:i.array(i.any())}),Pr=i.object({id:i.string(),name:i.string(),status:i.string(),uptime:i.string(),app_url:i.string(),app_id:i.string(),instance_id:i.string(),configuration:$r,exited_at:i.string(),boot_progress:i.string(),boot_error:i.string(),shutdown_progress:i.string(),image_version:i.string()}),Ir=i.object({id:i.number(),username:i.string()}),Dr=i.object({id:i.number(),name:i.string()}),Ne=i.object({hosted:Pr,name:i.string(),managed_user:Ir,node:Dr,listed:i.boolean(),status:i.string(),in_progress:i.boolean(),dapp_dashboard_url:i.string().nullable(),syslog_endpoint:i.string(),allow_upgrade:i.boolean()}),le=i.object({id:i.number(),name:i.string(),status:i.string(),teepod_id:i.number().nullable(),teepod:i.object({id:i.number(),name:i.string()}).nullable(),user_id:i.number(),app_id:i.string(),vm_uuid:i.string().nullable(),instance_id:i.string().nullable(),app_url:i.string().nullable(),base_image:i.string(),vcpu:i.number(),memory:i.number(),disk_size:i.number(),manifest_version:i.number(),version:i.string(),runner:i.string(),docker_compose_file:i.string(),features:i.array(i.string()).nullable(),created_at:i.string(),encrypted_env_pubkey:i.string()}),ut=i.object({app_env_encrypt_pubkey:i.string(),app_id_salt:i.string()}),dt=i.object({id:i.number(),teepod_id:i.number().nullable(),teepod:i.object({id:i.number(),name:i.string()}).nullable(),name:i.string(),status:i.string(),in_progress:i.boolean(),app_id:i.string(),vm_uuid:i.string(),instance_id:i.string(),vcpu:i.number(),memory:i.number(),disk_size:i.number(),base_image:i.string(),encrypted_env_pubkey:i.string(),listed:i.boolean(),project_id:i.string(),project_type:i.string().nullable()}),ft=i.object({username:i.string(),email:i.string(),credits:me.create({coerce:!0}),role:i.string(),avatar:i.string(),flag_reset_password:i.boolean(),team_name:i.string(),team_tier:i.string(),trial_ended_at:i.string().nullable()}),pn=i.array(Ne),gt=i.object({detail:i.string()}),ln=i.object({key:i.string(),value:i.string()}),Oe=i.object({name:i.string(),description:i.string().optional(),version:i.array(i.number()).optional(),is_dev:i.boolean().optional(),rootfs_hash:i.string().optional(),shared_ro:i.boolean().optional(),cmdline:i.string().optional(),kernel:i.string().optional(),initrd:i.string().optional(),hda:i.string().nullable().optional(),rootfs:i.string().optional(),bios:i.string().optional()}),Ar=i.object({teepod_id:i.number().nullable(),name:i.string(),listed:i.boolean(),resource_score:i.number(),remaining_vcpu:i.number(),remaining_memory:i.number(),remaining_cvm_slots:i.number(),images:i.array(Oe).optional()}),Rr=i.object({max_instances:i.number().nullable(),max_vcpu:i.number().nullable(),max_memory:i.number().nullable(),max_disk:i.number().nullable()}),ht=i.object({tier:i.string(),capacity:Rr,nodes:i.array(Ar)}),Fr=i.object({is_online:i.boolean(),is_public:i.boolean(),error:i.string().nullable(),internal_ip:i.string(),latest_handshake:i.string(),public_urls:i.array(i.object({app:i.string(),instance:i.string()}))}),yt=i.object({is_online:i.boolean(),is_public:i.boolean(),error:i.string().nullable(),app_certificates:i.array(i.object({subject:i.object({common_name:i.string().nullable(),organization:i.string().nullable(),country:i.string().nullable(),state:i.string().nullable().optional(),locality:i.string().nullable().optional()}),issuer:i.object({common_name:i.string().nullable(),organization:i.string().nullable(),country:i.string().nullable()}),serial_number:i.string(),not_before:i.string(),not_after:i.string(),version:i.string(),fingerprint:i.string(),signature_algorithm:i.string(),sans:i.string().nullable(),is_ca:i.boolean(),position_in_chain:i.number(),quote:i.string().nullable()})).nullable(),tcb_info:i.object({mrtd:i.string(),rootfs_hash:i.string(),rtmr0:i.string(),rtmr1:i.string(),rtmr2:i.string(),rtmr3:i.string(),event_log:i.array(i.object({imr:i.number(),event_type:i.number(),digest:i.string(),event:i.string(),event_payload:i.string()}))}).nullable(),compose_file:i.string().nullable()});function vt(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function j(){try{r.debug(`Fetching user info from ${E.USER_INFO}`);let t=await T.get(E.USER_INFO);r.debug(`Received response: ${vt(t)}`);try{return ft.parse(t)}catch(e){throw r.error(`Failed to parse user info response: ${e}`),r.debug(`Response structure: ${vt(t)}`),e}}catch(t){throw r.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 bt=new Mr().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 Vr({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 Fe(n),e=await j(),!e.username)return await se(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(await Fe(t),e=await j(),!e.username)return await se(),"Invalid API key";r.success(`Welcome ${e.username}! API key validated and saved successfully`),r.break(),r.info(`Open in Web UI at ${S}/dashboard/`)}catch(e){r.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Lr}from"commander";var Ct=new Lr().name("logout").description("Remove the stored API key").action(async()=>{try{await se(),r.success("API key removed successfully")}catch(t){r.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Nr}from"commander";var kt=new Nr().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 Y();if(!e){r.warn('Not authenticated. Please set an API key with "phala auth login"');return}r.debug(`Using API key: ${e.substring(0,5)}...`);let o=r.startSpinner("Checking authentication status");try{let n=await j();if(o.stop(!0),t.json){console.log(JSON.stringify(n,null,2));return}r.break(),r.success(`Authenticated as ${n.username}`);let s={Username:n.username,Email:n.email,Role:n.role,Team:`${n.team_name} (${n.team_tier})`,Credits:`$${n.credits}`};n.trial_ended_at&&(s["Trial Ended At"]=n.trial_ended_at),r.keyValueTable(s,{borderStyle:"rounded"})}catch(n){o.stop(!1),r.error("Authentication failed. Your API key may be invalid or expired."),r.info('Please set a new API key with "phala auth login"'),t.debug&&r.debug(`Error details: ${n instanceof Error?n.message:String(n)}`)}}catch(e){r.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var _t=new Or().name("auth").description("Authenticate with Phala Cloud").addCommand(bt).addCommand(Ct).addCommand(kt);import{Command as to}from"commander";import{Command as Zr}from"commander";import{execa as Tt}from"execa";import K from"node:fs";import Be from"node:path";import Wr from"handlebars";import{exec as Br,spawn as Gr}from"node:child_process";import{promisify as Kr}from"node:util";import qr from"node:os";import Ur from"inquirer";import Ue from"node:fs";import ze from"node:path";function W(t,e=process.cwd()){let o=ze.resolve(e,t);if(!Ue.existsSync(o))throw new Error(`File not found at ${o}`);return!0}async function B(t,e,o="file",n=process.cwd()){return(await Ur.prompt([{type:"input",name:o,message:t,default:e,validate:a=>{let c=ze.resolve(n,a);return Ue.existsSync(c)?!0:`File not found at ${c}`}}]))[o]}function ke(t,e){for(let o of t){let n=ze.join(process.cwd(),o);if(Ue.existsSync(n))return e?r.info(e.replace("{path}",n)):r.info(`File detected: ${n}`),o}}import*as A from"node:fs";import*as O from"node:path";import*as Q from"node:os";import{execSync as ee,spawn as zr}from"node:child_process";import*as je from"node:net";var I={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:O.join(Q.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:O.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 wt(){try{if(!A.existsSync(I.installDir))return!1;let t=Q.platform();if(!I.platforms[t])throw new Error(`Unsupported platform: ${t}`);let e=O.join(I.installDir,I.platforms[t].extractedFolder);if(!A.existsSync(e))return!1;let n=O.join(e,t==="win32"?"tappd-simulator.exe":"tappd-simulator");return A.existsSync(n)}catch(t){return r.error("Error checking if simulator is installed:",t),!1}}function ue(){let t=Q.platform();if(!I.platforms[t])throw new Error(`Unsupported platform: ${t}. Only darwin, linux, and win32 are supported.`);return t}async function St(t){let e=o=>{r.info(o),t&&t(o)};try{let o=ue(),n=I.platforms[o];A.existsSync(I.installDir)||(r.info(`Creating installation directory at ${I.installDir}`),A.mkdirSync(I.installDir,{recursive:!0})),process.chdir(I.installDir);let s=`${I.baseUrl}/${n.filename}`;r.info(`Downloading simulator from ${s}`),ee(`wget ${s}`,{stdio:"inherit"}),r.info(`Extracting ${n.filename}`),ee(`tar -xvf ${n.filename}`,{stdio:"inherit"}),r.success("Simulator installation completed successfully")}catch(o){throw r.error("Error installing simulator:",o),new Error(`Failed to install simulator: ${o}`)}}async function xt(t={}){try{let e=ue(),o=I.platforms[e],n=O.join(I.installDir,o.extractedFolder);process.chdir(n);let s=e==="win32"?"tappd-simulator.exe":"./tappd-simulator",a={background:t.background??!0,logToFile:t.logToFile??!0,logFilePath:t.logFilePath??I.defaultLogPath};if(a.logToFile){let f=O.dirname(a.logFilePath);A.existsSync(f)||A.mkdirSync(f,{recursive:!0}),r.info(`Simulator logs will be written to: ${a.logFilePath}`)}r.info(`Starting simulator with: ${s} -l ${o.socketArg}`);let c="inherit",u=null;a.logToFile&&(u=A.createWriteStream(a.logFilePath,{flags:"a"}),c=["ignore",u,u]);let h=zr(s,["-l",o.socketArg],{stdio:c,shell:e==="win32",detached:a.background});if(u){let f=new Date().toISOString();u.write(`
102
+ `;function Ne(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var Oe=class{client;apiKey=null;constructor(e){r.debug(`Creating API client with base URL: ${e}`),this.client=Sr.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${st}`}}),this.client.interceptors.request.use(async o=>{if(!this.apiKey){if(this.apiKey=await Y(),!this.apiKey)throw new Error('API key not found. Please set an API key first with "phala auth login"');r.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return o.headers["X-API-Key"]=this.apiKey,r.debug(`Making request to: ${o.baseURL}${o.url}`),o}),this.client.interceptors.response.use(o=>(r.debug(`Received successful response from: ${o.config.url}`),o),o=>{if(o.response){let{status:n,data:s}=o.response;r.debug(`Received error response: ${n} - ${Ne(s)}`),n===401?r.error("Authentication failed. Please check your API key."):n===403?r.error("You do not have permission to perform this action."):n===404?r.error("Resource not found."):r.error(`API Error (${n}): ${s.message||Ne(s)}`)}else o.request?(r.error("No response received from the server. Please check your internet connection."),r.debug(`Request details: ${Ne(o.request).substring(0,200)}...`)):r.error(`Error: ${o.message}`);return Promise.reject(o)})}async get(e,o){try{return r.debug(`GET request to: ${e}`),(await this.client.get(e,o)).data}catch(n){throw r.debug(`GET request failed: ${n instanceof Error?n.message:String(n)}`),n}}async post(e,o,n){try{return r.debug(`POST request to: ${e}`),(await this.client.post(e,o,n)).data}catch(s){throw r.debug(`POST request failed: ${s instanceof Error?s.message:String(s)}`),s}}async put(e,o,n){try{return r.debug(`PUT request to: ${e}`),(await this.client.put(e,o,n)).data}catch(s){throw r.debug(`PUT request failed: ${s instanceof Error?s.message:String(s)}`),s}}async delete(e,o){try{return r.debug(`DELETE request to: ${e}`),(await this.client.delete(e,o)).data}catch(n){throw r.debug(`DELETE request failed: ${n instanceof Error?n.message:String(n)}`),n}}async patch(e,o,n){try{return r.debug(`PATCH request to: ${e}`),(await this.client.patch(e,o,n)).data}catch(s){throw r.debug(`PATCH request failed: ${s instanceof Error?s.message:String(s)}`),s}}};r.debug(`Initializing API client with URL: ${Le}`);var $=new Oe(Le);import{z as i}from"zod";import{INVALID as xr,ParseStatus as Er,ZodIssueCode as J,ZodParsedType as pt,ZodType as $r,addIssueToContext as X,z as lt}from"zod";var Tr="ZodDecimal",Pr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,pe=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)!==pt.number){let a=this._getOrReturnCtx(e);return X(a,{code:J.invalid_type,expected:pt.number,received:a.parsedType}),xr}let n,s=new Er;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:J.custom,message:a.message,params:{precision:a.value}}),s.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.custom,message:a.message,params:{wholeNumber:a.value}}),s.dirty()):a.kind==="min"?(a.inclusive?e.data<a.value:e.data<=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.too_small,minimum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),s.dirty()):a.kind==="max"?(a.inclusive?e.data>a.value:e.data>=a.value)&&(n=this._getOrReturnCtx(e,n),X(n,{code:J.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),s.dirty()):a.kind==="finite"&&(Number.isFinite(e.data)||(n=this._getOrReturnCtx(e,n),X(n,{code:J.not_finite,message:a.message}),s.dirty()));return{status:s.value,value:e.data}}setLimit(e,o,n,s){return new pe({...this._def,checks:[...this._def.checks,{kind:e,value:o,inclusive:n,message:s}]})}_addCheck(e){return new pe({...this._def,checks:[...this._def.checks,e]})}lte(e,o){return this.setLimit("max",e,!0,o)}lt(e,o){return this.setLimit("max",e,!1,o)}max=this.lte;gt(e,o){return this.setLimit("min",e,!1,o)}gte(e,o){return this.setLimit("min",e,!0,o)}min=this.gte;precision(e,o){return this._addCheck({kind:"precision",value:e,message:o})}wholeNumber(e,o){return this._addCheck({kind:"wholeNumber",value:e,message:o})}get minValue(){let e=null;for(let o of this._def.checks)o.kind==="min"&&(e===null||o.value>e)&&(e=o.value);return e}get maxValue(){let e=null;for(let o of this._def.checks)o.kind==="max"&&(e===null||o.value<e)&&(e=o.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,o=null;for(let n of this._def.checks){if(n.kind==="finite")return!0;n.kind==="min"?(o===null||n.value>o)&&(o=n.value):n.kind==="max"&&(e===null||n.value<e)&&(e=n.value)}return Number.isFinite(o)&&Number.isFinite(e)}},me=pe;Je(me,"create",e=>new pe({checks:[],typeName:Tr,coerce:e?.coerce??!1}));var ut=lt.object({template:lt.string().min(1,"Template cannot be empty")});var Ir=i.object({password:i.string(),registry:i.string().nullable(),username:i.string()}),Dr=i.object({docker_compose_file:i.string(),docker_config:Ir.optional(),features:i.array(i.string()),kms_enabled:i.boolean(),manifest_version:i.number(),name:i.string(),public_logs:i.boolean(),public_sysinfo:i.boolean(),runner:i.string().optional(),salt:i.string().nullable().optional(),tproxy_enabled:i.boolean(),version:i.string().optional()}),Ar=i.object({name:i.string(),image:i.string(),compose_file:Dr,vcpu:i.number(),memory:i.number(),disk_size:i.number(),ports:i.array(i.any())}),Rr=i.object({id:i.string(),name:i.string(),status:i.string(),uptime:i.string(),app_url:i.string(),app_id:i.string(),instance_id:i.string(),configuration:Ar,exited_at:i.string(),boot_progress:i.string(),boot_error:i.string(),shutdown_progress:i.string(),image_version:i.string()}),Fr=i.object({id:i.number(),username:i.string()}),Mr=i.object({id:i.number(),name:i.string()}),Ue=i.object({hosted:Rr,name:i.string(),managed_user:Fr,node:Mr,listed:i.boolean(),status:i.string(),in_progress:i.boolean(),dapp_dashboard_url:i.string().nullable(),syslog_endpoint:i.string(),allow_upgrade:i.boolean()}),le=i.object({id:i.number(),name:i.string(),status:i.string(),teepod_id:i.number().nullable(),teepod:i.object({id:i.number(),name:i.string()}).nullable(),user_id:i.number(),app_id:i.string(),vm_uuid:i.string().nullable(),instance_id:i.string().nullable(),app_url:i.string().nullable(),base_image:i.string(),vcpu:i.number(),memory:i.number(),disk_size:i.number(),manifest_version:i.number(),version:i.string(),runner:i.string(),docker_compose_file:i.string(),features:i.array(i.string()).nullable(),created_at:i.string(),encrypted_env_pubkey:i.string()}),dt=i.object({app_env_encrypt_pubkey:i.string(),app_id_salt:i.string()}),ft=i.object({id:i.number(),teepod_id:i.number().nullable(),teepod:i.object({id:i.number(),name:i.string()}).nullable(),name:i.string(),status:i.string(),in_progress:i.boolean(),app_id:i.string(),vm_uuid:i.string(),instance_id:i.string(),vcpu:i.number(),memory:i.number(),disk_size:i.number(),base_image:i.string(),encrypted_env_pubkey:i.string(),listed:i.boolean(),project_id:i.string(),project_type:i.string().nullable()}),gt=i.object({username:i.string(),email:i.string(),credits:me.create({coerce:!0}),role:i.string(),avatar:i.string(),flag_reset_password:i.boolean(),team_name:i.string(),team_tier:i.string(),trial_ended_at:i.string().nullable()}),hn=i.array(Ue),ht=i.object({detail:i.string()}),yn=i.object({key:i.string(),value:i.string()}),ze=i.object({name:i.string(),description:i.string().optional(),version:i.array(i.number()).optional(),is_dev:i.boolean().optional(),rootfs_hash:i.string().optional(),shared_ro:i.boolean().optional(),cmdline:i.string().optional(),kernel:i.string().optional(),initrd:i.string().optional(),hda:i.string().nullable().optional(),rootfs:i.string().optional(),bios:i.string().optional()}),Vr=i.object({teepod_id:i.number().nullable(),name:i.string(),listed:i.boolean(),resource_score:i.number(),remaining_vcpu:i.number(),remaining_memory:i.number(),remaining_cvm_slots:i.number(),images:i.array(ze).optional()}),Lr=i.object({max_instances:i.number().nullable(),max_vcpu:i.number().nullable(),max_memory:i.number().nullable(),max_disk:i.number().nullable()}),yt=i.object({tier:i.string(),capacity:Lr,nodes:i.array(Vr)}),Nr=i.object({is_online:i.boolean(),is_public:i.boolean(),error:i.string().nullable(),internal_ip:i.string(),latest_handshake:i.string(),public_urls:i.array(i.object({app:i.string(),instance:i.string()}))}),bt=i.object({is_online:i.boolean(),is_public:i.boolean(),error:i.string().nullable(),app_certificates:i.array(i.object({subject:i.object({common_name:i.string().nullable(),organization:i.string().nullable(),country:i.string().nullable(),state:i.string().nullable().optional(),locality:i.string().nullable().optional()}),issuer:i.object({common_name:i.string().nullable(),organization:i.string().nullable(),country:i.string().nullable()}),serial_number:i.string(),not_before:i.string(),not_after:i.string(),version:i.string(),fingerprint:i.string(),signature_algorithm:i.string(),sans:i.string().nullable(),is_ca:i.boolean(),position_in_chain:i.number(),quote:i.string().nullable()})).nullable(),tcb_info:i.object({mrtd:i.string(),rootfs_hash:i.string(),rtmr0:i.string(),rtmr1:i.string(),rtmr2:i.string(),rtmr3:i.string(),event_log:i.array(i.object({imr:i.number(),event_type:i.number(),digest:i.string(),event:i.string(),event_payload:i.string()}))}).nullable(),compose_file:i.string().nullable()});function vt(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function j(){try{r.debug(`Fetching user info from ${E.USER_INFO}`);let t=await $.get(E.USER_INFO);r.debug(`Received response: ${vt(t)}`);try{return gt.parse(t)}catch(e){throw r.error(`Failed to parse user info response: ${e}`),r.debug(`Response structure: ${vt(t)}`),e}}catch(t){throw r.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 Ct=new Or().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 Ur({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 Ve(n),e=await j(),!e.username)return await se(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(await Ve(t),e=await j(),!e.username)return await se(),"Invalid API key";r.success(`Welcome ${e.username}! API key validated and saved successfully`),r.break(),r.info(`Open in Web UI at ${S}/dashboard/`)}catch(e){r.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as zr}from"commander";var kt=new zr().name("logout").description("Remove the stored API key").action(async()=>{try{await se(),r.success("API key removed successfully")}catch(t){r.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as jr}from"commander";var wt=new jr().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 Y();if(!e){r.warn('Not authenticated. Please set an API key with "phala auth login"');return}r.debug(`Using API key: ${e.substring(0,5)}...`);let o=r.startSpinner("Checking authentication status");try{let n=await j();if(o.stop(!0),t.json){console.log(JSON.stringify(n,null,2));return}r.break(),r.success(`Authenticated as ${n.username}`);let s={Username:n.username,Email:n.email,Role:n.role,Team:`${n.team_name} (${n.team_tier})`,Credits:`$${n.credits}`};n.trial_ended_at&&(s["Trial Ended At"]=n.trial_ended_at),r.keyValueTable(s,{borderStyle:"rounded"})}catch(n){o.stop(!1),r.error("Authentication failed. Your API key may be invalid or expired."),r.info('Please set a new API key with "phala auth login"'),t.debug&&r.debug(`Error details: ${n instanceof Error?n.message:String(n)}`)}}catch(e){r.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var _t=new Br().name("auth").description("Authenticate with Phala Cloud").addCommand(Ct).addCommand(kt).addCommand(wt);import{Command as so}from"commander";import{Command as Qr}from"commander";import{execa as Tt}from"execa";import K from"node:fs";import Ke from"node:path";import Hr from"handlebars";import{exec as qr,spawn as Zr}from"node:child_process";import{promisify as Yr}from"node:util";import Jr from"node:os";import Wr from"inquirer";import je from"node:fs";import Be from"node:path";function B(t,e=process.cwd()){let o=Be.resolve(e,t);if(!je.existsSync(o))throw new Error(`File not found at ${o}`);return!0}async function W(t,e,o="file",n=process.cwd()){return(await Wr.prompt([{type:"input",name:o,message:t,default:e,validate:a=>{let c=Be.resolve(n,a);return je.existsSync(c)?!0:`File not found at ${c}`}}]))[o]}function _e(t,e){for(let o of t){let n=Be.join(process.cwd(),o);if(je.existsSync(n))return e?r.info(e.replace("{path}",n)):r.info(`File detected: ${n}`),o}}import*as A from"node:fs";import*as O from"node:path";import*as Q from"node:os";import{execSync as ee,spawn as Gr}from"node:child_process";import*as We from"node:net";var I={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:O.join(Q.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:O.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(!A.existsSync(I.installDir))return!1;let t=Q.platform();if(!I.platforms[t])throw new Error(`Unsupported platform: ${t}`);let e=O.join(I.installDir,I.platforms[t].extractedFolder);if(!A.existsSync(e))return!1;let n=O.join(e,t==="win32"?"tappd-simulator.exe":"tappd-simulator");return A.existsSync(n)}catch(t){return r.error("Error checking if simulator is installed:",t),!1}}function ue(){let t=Q.platform();if(!I.platforms[t])throw new Error(`Unsupported platform: ${t}. Only darwin, linux, and win32 are supported.`);return t}async function xt(t){let e=o=>{r.info(o),t&&t(o)};try{let o=ue(),n=I.platforms[o];A.existsSync(I.installDir)||(r.info(`Creating installation directory at ${I.installDir}`),A.mkdirSync(I.installDir,{recursive:!0})),process.chdir(I.installDir);let s=`${I.baseUrl}/${n.filename}`;r.info(`Downloading simulator from ${s}`),ee(`wget ${s}`,{stdio:"inherit"}),r.info(`Extracting ${n.filename}`),ee(`tar -xvf ${n.filename}`,{stdio:"inherit"}),r.success("Simulator installation completed successfully")}catch(o){throw r.error("Error installing simulator:",o),new Error(`Failed to install simulator: ${o}`)}}async function Et(t={}){try{let e=ue(),o=I.platforms[e],n=O.join(I.installDir,o.extractedFolder);process.chdir(n);let s=e==="win32"?"tappd-simulator.exe":"./tappd-simulator",a={background:t.background??!0,logToFile:t.logToFile??!0,logFilePath:t.logFilePath??I.defaultLogPath};if(a.logToFile){let f=O.dirname(a.logFilePath);A.existsSync(f)||A.mkdirSync(f,{recursive:!0}),r.info(`Simulator logs will be written to: ${a.logFilePath}`)}r.info(`Starting simulator with: ${s} -l ${o.socketArg}`);let c="inherit",u=null;a.logToFile&&(u=A.createWriteStream(a.logFilePath,{flags:"a"}),c=["ignore",u,u]);let h=Gr(s,["-l",o.socketArg],{stdio:c,shell:e==="win32",detached:a.background});if(u){let f=new Date().toISOString();u.write(`
103
103
  [${f}] Simulator started
104
- `)}return a.background&&(h.unref(),r.success("Simulator is running in the background")),await We(),h}catch(e){throw r.error("Error running simulator:",e),new Error(`Failed to run simulator: ${e}`)}}async function _e(){try{let t=ue(),e=I.platforms[t];if(t==="darwin"||t==="linux"){let o="/tmp/tappd.sock";return A.existsSync(o)?new Promise(n=>{let s=je.createConnection({path:o}).on("connect",()=>{s.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{s.end(),n(!1)},1e3)}):!1}if(t==="win32"){let o="127.0.0.1";return new Promise(s=>{let a=je.createConnection({host:o,port:8090}).on("connect",()=>{a.end(),s(!0)}).on("error",()=>{s(!1)});setTimeout(()=>{a.end(),s(!1)},1e3)})}return!1}catch(t){return r.error("Error checking if simulator is running:",t),!1}}async function Et(){try{let t=ue();if(!await _e())return r.info("Simulator is not running"),!0;r.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 _e();return e?r.success("Simulator stopped successfully"):r.error("Failed to stop simulator"),await G(),e}catch(t){return r.error("Error stopping simulator:",t),!1}}function jr(){return ue()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function We(t){try{let e=jr(),o=t||e;return await ee(`export DSTACK_SIMULATOR_ENDPOINT=${o}`),r.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${o} for current process`),t}catch(e){throw r.error("Error setting simulator endpoint environment variable:",e),new Error(`Failed to set simulator endpoint: ${e}`)}}async function G(){return await ee("unset DSTACK_SIMULATOR_ENDPOIN"),r.success("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var de=Kr(Br),$t=".phala-cloud/logs",Hr=".phala-cloud/compose",Pt=10,$=class{username;image;registry;constructor(e,o,n){this.image=e,this.username=o||"",this.registry=n||""}ensureLogsDir(){let e=Be.resolve($t);K.existsSync(e)||K.mkdirSync(e,{recursive:!0})}getLogFilePath(e,o){let n=new Date().toISOString().replace(/[:.]/g,"-");return Be.resolve($t,`${o||this.image}-${e}-${n}.log`)}getSystemArchitecture(){let e=qr.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,o,n,s){return new Promise((a,c)=>{let u=Gr(e,o);this.ensureLogsDir();let h=this.getLogFilePath(n,s),f=K.createWriteStream(h,{flags:"a"}),C=[],v=(p,m=!1)=>{let l=p.toString().split(`
105
- `);f.write(p),l.forEach(g=>{g.trim()&&(C.push(g),C.length>Pt&&C.shift(),console.clear(),console.log(`Latest ${Pt} lines (full log at ${h}):`),console.log("-".repeat(50)),C.forEach(y=>{m?console.error(y):console.log(y)}))})};u.stdout.on("data",p=>v(p)),u.stderr.on("data",p=>v(p,!0)),u.on("close",p=>{f.end(),p===0?(console.log(`
106
- Operation completed. Full log available at: ${h}`),a()):c(new Error(`Process exited with code ${p}. Check log file: ${h}`))}),u.on("error",p=>{f.end(),c(p)})})}setCredentials(e,o){this.username=e,o&&(this.registry=o)}async buildImage(e,o){try{let n=this.getSystemArchitecture(),s=`${this.username}/${this.image}:${o}`,a=r.startSpinner(`Building Docker image ${this.username}/${this.image}:${o}`);W(e);let c=["build","-t",s,"-f",e];return n==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),c.push("--platform","linux/amd64")),c.push("."),await this.spawnProcess("docker",c,"build",this.image),a.stop(!0,`Docker image ${s} built successfully`),!0}catch(n){return r.error(`Failed to build Docker image: ${n instanceof Error?n.message:String(n)}`),!1}}async pushImage(e){try{let o=r.startSpinner(`Pushing Docker image ${e} to Docker Hub`);if(!await L())throw o.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let s=e;return console.log(`Pushing image ${s} to Docker Hub...`),await this.spawnProcess("docker",["push",s],"push",e.replace(/.*\/+(\w+):.*$/g,"$1")),o.stop(!0,`Docker image ${s} pushed successfully`),!0}catch(o){return r.error(`Failed to push Docker image: ${o instanceof Error?o.message:String(o)}`),!1}}async login(e,o,n){try{let s=r.startSpinner(`Logging in to Docker Hub as ${e}`);return await this.checkLogin()?(s.stop(!0,`Logged in as ${e}`),this.setCredentials(e,n),!0):(await Tt("docker",["login",...n?[n]:[],"-u",e,"--password-stdin"],{input:o}),s.stop(!0,"Logged in to Docker Hub successfully"),!0)}catch(s){return r.error(`Failed to login to Docker Hub: ${s instanceof Error?s.message:String(s)}`),!1}}async checkLogin(){try{let{stdout:e}=await Tt("docker",["login"]);return e.includes("Login Succeeded")}catch{return!1}}async buildComposeFile(e,o,n){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let s=n==="eliza"?at:ct,a=lt.parse({template:s}),c=Hr;K.existsSync(c)||(r.info(`Creating directory: ${c}`),K.mkdirSync(c,{recursive:!0}));let u=[];o&&(u=K.readFileSync(o,"utf-8").split(`
107
- `).filter(m=>m&&!m.startsWith("#")).map(m=>{let l=m.indexOf("#");return l>0&&(m=m.substring(0,l).trim()),m.trim()}).filter(m=>m.includes("=")).map(m=>{let[l,g]=m.split("=",2),y=l.trim();return(g?g.trim():"")===""?null:`${y}=${y}`}).filter(Boolean));let h=e,C=Wr.compile(a.template,{noEscape:!0})({imageName:h,envVars:u.map(p=>p.replace(/=.*/,"=${"+p.split("=")[0]+"}"))}),v=Be.join(c,`${e.replace(/.*\/+(\w+):.*$/g,"$1")}-tee-compose.yaml`);return K.writeFileSync(v,C),r.success(`Backup of docker compose file created at: ${v}`),v}async runComposeLocally(e,o){try{let n=r.startSpinner(`Running Docker Compose file at ${e}`);W(e);let s=["-f",e,"up","-d"];return o&&(W(o),s.splice(2,0,"--env-file",o)),await de(`docker compose ${s.join(" ")}`),n.stop(!0,"Docker Compose file running successfully"),!0}catch(n){return r.error(`Failed to run Docker Compose file: ${n instanceof Error?n.message:String(n)}`),!1}}async runSimulator(e,o){try{r.info(`Running TEE simulator with image ${e}`),r.info("Pulling latest simulator image..."),await de(`docker pull ${e}`),r.info("Starting simulator in background...");let{stdout:n}=await de(`docker run -d --name tee-simulator --rm -p ${o}:${o} ${e}`),s=n.trim();return r.success(`TEE simulator running successfully. Container ID: ${s}`),r.break(),r.break(),r.info("Useful commands:"),r.info(`- View logs: docker logs -f ${s}`),r.info(`- Stop simulator: docker stop ${s}`),We(`http://localhost:${o}`),!0}catch(n){return r.error(`Failed to run TEE simulator: ${n instanceof Error?n.message:String(n)}`),!1}}async stopSimulator(){try{let e=r.startSpinner("Stopping TEE simulator...");return await de("docker stop tee-simulator"),await G(),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return r.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),!1}}static async listLocalImages(){try{let{stdout:e}=await de('docker images --format "{{.Repository}}:{{.Tag}}"'),n=(await L())?.username;return e.split(`
108
- `).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${n}/`)).map(a=>({imageName:a}))}catch(e){return r.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import It from"prompts";var Dt=new Zr().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,o=t.password,n=t.registry;if(!e){r.info("First we need your Docker Hub username to check if you are already logged in.");let u=await It({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:h=>h.length>0?!0:"Username cannot be empty"});u.username||(r.error("Username is required"),process.exit(1)),e=u.username}let s=new $("",e,n);if(await s.login(e)){r.success(`${e} is logged in to Docker Hub`);return}if(!o){let u=await It({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:h=>h.length>0?!0:"Password cannot be empty"});u.password||(r.error("Password is required"),process.exit(1)),o=u.password}await s.login(e,o,n)||(r.error("Failed to login to Docker Hub"),process.exit(1)),await ot({username:e,registry:n||null}),r.success("Logged in to Docker Hub successfully")}catch(e){r.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Yr}from"commander";import At from"node:path";import Rt from"inquirer";import Jr from"node:fs";var Ft=new Yr().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 L();if(e||(r.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!t.image){let c=await Rt.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:u=>u.trim()?!0:"Image name is required"}]);t.image=c.image}if(!t.tag){let c=await Rt.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:u=>u.trim()?!0:"Tag is required"}]);t.tag=c.tag}let o=At.resolve(process.cwd(),t.file);Jr.existsSync(o)||(r.info(`Default Dockerfile not found at ${o}`),t.file=await B("Enter the path to your Dockerfile:","Dockerfile","file"));let n=At.resolve(process.cwd(),t.file);await new $(t.image,e.username,e.registry).buildImage(n,t.tag)||(r.error("Failed to build Docker image"),process.exit(1)),r.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){r.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Xr}from"commander";import Qr from"inquirer";var Mt=new Xr().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 L();e||(r.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let o=t.image;if(!o){let a=await $.listLocalImages();if(a.length===0&&(r.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!o){let c=Array.from(new Set(a.map(h=>h.imageName))),{selectedImage:u}=await Qr.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:c}]);o=u}}await new $("",e.username,e.registry).pushImage(o)||(r.error("Failed to push Docker image"),process.exit(1)),r.success(`Docker image ${o} pushed successfully`)}catch(e){r.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as eo}from"commander";import fe from"inquirer";import ge from"node:fs";import we from"node:path";var Vt=new eo().name("generate").description("Generate a Docker Compose file").option("-i, --image <imageName>","Docker image name to use in the compose file (e.g. phala/phala-cloud)").option("-e, --env-file <envFile>","Path to environment variables file").option("-o, --output <output>","Output path for generated docker-compose.yml").option("--template <template>","Template to use for the generated docker-compose.yml").action(async t=>{try{let e=await L();(!e||!e.username)&&(r.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let o=t.image;if(!o){let u=await $.listLocalImages();if(u.length===0&&(r.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!o){let h=Array.from(new Set(u.map(C=>C.imageName))),{selectedImage:f}=await fe.prompt([{type:"list",name:"selectedImage",message:"Select an image to use in the compose file:",choices:h}]);o=f}}let n=t.envFile;if(n)try{W(n)}catch{r.error(`File not found: ${n}`),process.exit(1)}else{let u=we.join(process.cwd(),".env");if(ge.existsSync(u)){let{useDefault:f}=await fe.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);f&&(n=u)}if(!n){let{envPath:f}=await fe.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:C=>{try{return W(C),!0}catch{return`File not found: ${C}`}}}]);n=f}}let s=t.output;if(!s&&(s=we.join(process.cwd(),"docker-compose.yml"),ge.existsSync(s))){let{confirmOverwrite:u}=await fe.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${s} already exists. Overwrite?`,default:!1}]);if(!u){let{customPath:h}=await fe.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:we.join(process.cwd(),"docker-generated-compose.yml")}]);s=h}}let a=new $("",e.username,e.registry);n?r.info(`Generating Docker Compose file for ${o} using env file: ${n}`):r.info(`Generating Docker Compose file for ${o} without env file`);let c=await a.buildComposeFile(o,n,t.template);if(c!==s){let u=we.dirname(s);ge.existsSync(u)||(r.info(`Creating directory: ${u}`),ge.mkdirSync(u,{recursive:!0})),ge.copyFileSync(c,s)}r.success(`Docker Compose file generated successfully: ${s}`)}catch(e){r.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Lt=new to().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(Dt).addCommand(Ft).addCommand(Mt).addCommand(Vt);import{Command as no}from"commander";import{Command as ro}from"commander";var Nt=new ro().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",st).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)||(r.error("Failed to start TEE simulator"),process.exit(1));else if(t.type==="native")if(wt()||await St(),await _e()){r.success("TEE simulator is already running");return}else{let o=xt();r.success("TEE simulator started successfully")}else r.error("Invalid simulator type"),process.exit(1)}catch(e){r.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as oo}from"commander";var Ot=new oo().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()||(r.error("Failed to stop TEE simulator"),process.exit(1)):t.type==="native"?await Et()||(r.error("Failed to stop TEE simulator"),process.exit(1)):(r.error("Invalid simulator type"),process.exit(1))}catch(e){r.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Ut=new no().name("simulator").description("TEE simulator commands").addCommand(Nt).addCommand(Ot);import{Command as So}from"commander";import{Command as io}from"commander";import so from"inquirer";import{z as zt}from"zod";async function Se(){try{let t=await T.get(E.CVMS(0));return zt.array(Ne).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function xe(t){let o=(await Se()).find(n=>n.hosted?.app_id===t||`app_${n.hosted?.app_id}`===t);if(!o)r.error(`CVM with App ID app_${t} not detected`),process.exit(1);else return r.success(`CVM with App ID app_${t} detected`),o.hosted?.app_id||""}async function te(t){try{let e=await T.get(E.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 Ee(t){try{let e=await T.post(E.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 Te(t){try{let e=await T.post(E.CVM_FROM_CONFIGURATION,t);return le.parse(e)}catch(e){throw e instanceof zt.ZodError?(r.error("Schema validation error:",JSON.stringify(e.errors,null,2)),r.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{let e=await T.post(E.CVM_START(t));return le.parse(e)}catch(e){throw new Error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Wt(t){try{let e=await T.post(E.CVM_STOP(t));return le.parse(e)}catch(e){throw new Error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Bt(t){try{let e=await T.post(E.CVM_RESTART(t));return le.parse(e)}catch(e){throw new Error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Gt(t,e){try{let o=await T.put(E.CVM_UPGRADE(t),e);return gt.parse(o)}catch(o){throw new Error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`)}}async function Kt(t){try{return await T.delete(E.CVM_BY_APP_ID(t)),!0}catch(e){throw new Error(`Failed to delete CVM: ${e instanceof Error?e.message:String(e)}`)}}async function $e(){let t=r.startSpinner("Fetching available CVMs"),e=await Se();if(t.stop(!0),!e||e.length===0){r.info("No CVMs found for your account");return}let o=e.map(s=>{let a=s.hosted?.app_id||s.hosted?.id,c=s.name||s.hosted?.name,u=s.status||s.hosted?.status;return{name:`${c||"Unnamed"} (${a}) - Status: ${u||"Unknown"}`,value:a}}),{selectedCvm:n}=await so.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:o}]);return n}async function qt(t){try{let e=await T.get(E.CVM_ATTESTATION(t));try{return yt.parse(e)}catch(o){return r.debug(`Validation error: ${o instanceof Error?o.message:String(o)}`),{is_online:!!e?.is_online,is_public:!!e?.is_public,error:typeof e?.error=="string"?e.error:null,app_certificates:Array.isArray(e?.app_certificates)?e.app_certificates:null,tcb_info:e?.tcb_info||null,compose_file:typeof e?.compose_file=="string"?e.compose_file:null}}}catch(e){throw new Error(`Failed to get attestation information: ${e instanceof Error?e.message:String(e)}`)}}async function Ht(t,e,o,n,s){try{let a={};if(e!==void 0&&(a.vcpu=e),o!==void 0&&(a.memory=o),n!==void 0&&(a.disk_size=n),s!==void 0&&(a.allow_restart=s),Object.keys(a).length===0)throw new Error("At least one resource parameter must be provided");return await T.patch(E.CVM_RESIZE(t),a),!0}catch(a){throw new Error(`Failed to resize CVM: ${a instanceof Error?a.message:String(a)}`)}}import Ge from"chalk";var Zt=new io().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=r.startSpinner("Fetching CVMs"),o=await Se();if(e.stop(!0),!o||o.length===0){r.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(o,null,2));return}for(let n of o)r.keyValueTable({Name:n.name,"App ID":`app_${n.hosted.app_id}`,Status:n.status==="running"?Ge.green(n.status):n.status==="stopped"?Ge.red(n.status):Ge.yellow(n.status),"Node Info URL":n.hosted.app_url,"App URL":`${S}/dashboard/cvms/app_${n.hosted.app_id}`}),r.break();r.success(`Found ${o.length} CVMs`),r.break(),r.info(`Go to ${S}/dashboard/ to view your CVMs`)}catch(e){r.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ao}from"commander";import Ke from"chalk";async function D(t){if(!t){let e=await $e();return e||void 0}return await xe(t)}var Yt=new ao().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{let o=await D(t),n=r.startSpinner(`Fetching CVM with App ID app_${o}`),s=await te(o);if(n.stop(!0),r.break(),s||(r.error(`CVM with App ID app_${o} not found`),process.exit(1)),e.json){console.log(JSON.stringify(s,null,2));return}r.keyValueTable({Name:s.name,"App ID":`app_${s.app_id}`,Status:s.status==="running"?Ke.green(s.status):s.status==="stopped"?Ke.red(s.status):Ke.yellow(s.status),vCPU:s.vcpu,Memory:`${s.memory} MB`,"Disk Size":`${s.disk_size} GB`,"Dstack Image":s.base_image,"App URL":`${S}/dashboard/cvms/app_${s.app_id}`})}catch(o){r.error(`Failed to get CVM details: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as co}from"commander";var Jt=new co().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{let e=await D(t),o=r.startSpinner(`Starting CVM with App ID app_${e}`),n=await jt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being started. You can check the dashboard for more details:
109
- ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as mo}from"commander";var Xt=new mo().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{let e=await D(t),o=r.startSpinner(`Stopping CVM with App ID app_${e}`),n=await Wt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being stopped. You can check the dashboard for more details:
110
- ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as po}from"commander";var Qt=new po().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{let e=await D(t),o=r.startSpinner(`Restarting CVM with App ID app_${e}`),n=await Bt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`,"App URL":n.app_url?n.app_url:`${S}/dashboard/cvms/app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being restarted. You can check the dashboard for more details:
111
- ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as lo}from"commander";import Pe from"chalk";var er=new lo().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{let o;if(t)o=await xe(t);else{r.info("No CVM specified, fetching available CVMs...");let s=await $e();if(!s)return;o=s}let n=r.startSpinner(`Fetching attestation information for CVM app_${o}...`);try{let s=await qt(o);if(n.stop(!0),!s||Object.keys(s).length===0){r.info("No attestation information found");return}if(e?.json){r.info(JSON.stringify(s,null,2));return}r.success("Attestation Summary:");let a={Status:s.is_online?Pe.green("Online"):Pe.red("Offline"),"Public Access":s.is_public?Pe.green("Enabled"):Pe.yellow("Disabled"),Error:s.error||"None",Certificates:`${s.app_certificates?.length||0} found`};if(r.keyValueTable(a,{borderStyle:"rounded"}),s.app_certificates&&s.app_certificates.length>0&&s.app_certificates.forEach((c,u)=>{r.break(),r.success(`Certificate #${u+1} (${c.position_in_chain===0?"End Entity":"CA"}):`);let h={Subject:`${c.subject.common_name||"Unknown"}${c.subject.organization?` (${c.subject.organization})`:""}`,Issuer:`${c.issuer.common_name||"Unknown"}${c.issuer.organization?` (${c.issuer.organization})`:""}`,"Serial Number":c.serial_number,Validity:`${new Date(c.not_before).toLocaleString()} to ${new Date(c.not_after).toLocaleString()}`,Fingerprint:c.fingerprint,"Signature Algorithm":c.signature_algorithm,"Is CA":c.is_ca?"Yes":"No","Position in Chain":c.position_in_chain};r.keyValueTable(h,{borderStyle:"rounded"})}),s.tcb_info){r.break(),r.success("Trusted Computing Base (TCB) Information:");let c={Mrtd:s.tcb_info.mrtd,"Rootfs Hash":s.tcb_info.rootfs_hash,Rtmr0:s.tcb_info.rtmr0,Rtmr1:s.tcb_info.rtmr1,Rtmr2:s.tcb_info.rtmr2,Rtmr3:s.tcb_info.rtmr3,"Event Log Entries":`${s.tcb_info.event_log.length} entries`};if(r.keyValueTable(c,{borderStyle:"rounded"}),s.tcb_info.event_log&&s.tcb_info.event_log.length>0){r.break(),r.success("Event Log (Showing entries to reproduce RTMR3):");let u=5,h=s.tcb_info.event_log.filter(f=>f.event!==null&&f.event!=="").map(f=>({Event:f.event,IMR:f.imr.toString(),"Event Type":f.event_type.toString(),Payload:f.event_payload}));r.table(h,[{key:"Event",header:"Event",minWidth:8},{key:"IMR",header:"IMR",minWidth:3},{key:"Event Type",header:"Type",minWidth:8},{key:"Payload",header:"Payload",minWidth:25}]),s.tcb_info.event_log.length>u&&r.info("To see all full attestation data, use --json"),r.break(),r.success("To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/")}}}catch(s){throw n.stop(!1),s}}catch(o){r.error(`Failed to get attestation information: ${o instanceof Error?o.message:String(o)}`)}});import{Command as go}from"commander";import{z as uo}from"zod";async function qe(){try{let t=await T.get(E.TEEPODS);return ht.parse(t).nodes}catch(t){throw new Error(`Failed to get TEEPods: ${t instanceof Error?t.message:String(t)}`)}}async function tr(t){try{let o=(await qe()).find(s=>s.teepod_id===Number(t));if(o&&o.images&&o.images.length>0)return o.images;let n=await T.get(E.TEEPOD_IMAGES(t));return uo.array(Oe).parse(n)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}import{encryptEnvVars as ho}from"@phala/dstack-sdk/encrypt-env-vars";import rr from"node:fs";import yo from"node:path";import he from"inquirer";import fo from"node:fs";var q=(t,e)=>{let o={};if(t){for(let n of t)if(n.includes("=")){let[s,a]=n.split("=");s&&a&&(o[s]=a)}}if(e){let n=fo.readFileSync(e,"utf8");for(let s of n.split(`
112
- `))if(!(!s.trim()||s.trim().startsWith("#"))&&s.includes("=")){let[a,...c]=s.split("="),u=c.join("="),h=u.search(/\s+#/);h!==-1&&(u=u.substring(0,h).trim()),a&&u&&(o[a.trim()]=u.trim())}}return Object.entries(o).map(([n,s])=>({key:n,value:s}))};var or=new go().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(ie)).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",it).option("--image <image>","Version of dstack image to use",Ce).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 B("Enter the path to your Docker Compose file:",l,"file")}let e=yo.resolve(t.compose);rr.existsSync(e)||(r.error(`Docker Compose file not found: ${e}`),process.exit(1));let o=rr.readFileSync(e,"utf8");await G();let n=[];if(t.envFile)try{n=q([],t.envFile)}catch(m){r.error(`Failed to read environment file: ${m instanceof Error?m.message:String(m)}`),process.exit(1)}else if(!t.skipEnv){let{shouldSkip:m}=await he.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!0}]);if(m)r.info("Skipping environment variable prompt");else{let l=await B("Enter the path to your environment file:",".env","file");n=q([],l)}}let s=[];if(t.vcpu===String(ie)&&s.push({type:"input",name:"vcpu",message:`Enter number of vCPUs (default: ${ie}):`,default:String(ie),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.memory===String(ae)&&s.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)&&s.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}}),s.length>0){let m=await he.prompt(s);m.vcpu&&(t.vcpu=m.vcpu),m.memory&&(t.memory=m.memory),m.diskSize&&(t.diskSize=m.diskSize)}if(!t.teepodId){let m=r.startSpinner("Fetching available TEEPods"),l=await qe();m.stop(!0),l.length===0&&(r.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:g}=await he.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:l.map(d=>({name:`${d.name}`,value:d.teepod_id}))}]),y=l.find(d=>d.teepod_id===g);y||(r.error("Failed to find selected TEEPod"),process.exit(1)),r.info(`Selected TEEPod: ${y.name}`),t.teepodId=y.teepod_id}if(!t.image){let l=(await tr(t.teepodId)).map(y=>({name:`${y.name}`,value:y.name})),{selectedImage:g}=await he.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:l}]);t.image=g.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:o,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=r.startSpinner("Getting public key from CVM"),u=await Ee(a);c.stop(!0),u||(r.error("Failed to get public key from CVM"),process.exit(1));let h=r.startSpinner("Encrypting environment variables"),f=await ho(n,u.app_env_encrypt_pubkey);h.stop(!0),t.debug&&(r.debug("Public key:",u.app_env_encrypt_pubkey),r.debug("Encrypted environment variables:",f),r.debug("Environment variables:",JSON.stringify(n)));let C=r.startSpinner("Creating CVM"),v=await Te({...a,encrypted_env:f,app_env_encrypt_pubkey:u.app_env_encrypt_pubkey,app_id_salt:u.app_id_salt});C.stop(!0),v||(r.error("Failed to create CVM"),process.exit(1)),r.success("CVM created successfully"),r.break();let p={"CVM ID":v.id,Name:v.name,Status:v.status,"App ID":`app_${v.app_id}`,"App URL":v.app_url?v.app_url:`${S}/dashboard/cvms/app_${v.app_id}`};r.keyValueTable(p,{borderStyle:"rounded"}),r.info(""),r.success(`Your CVM is being created. You can check its status with:
113
- phala cvms get app_${v.app_id}`)}catch(e){r.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as vo}from"commander";import bo from"inquirer";var nr=new vo().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{let o=await D(t);if(!e.force){let{confirm:a}=await bo.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID app_${o}? This action cannot be undone.`,default:!1}]);if(!a){r.info("Deletion cancelled");return}}let n=r.startSpinner(`Deleting CVM app_${o}`),s=await Kt(o);n.stop(!0),s||(r.error(`Failed to delete CVM app_${o}`),process.exit(1)),r.success(`CVM app_${o} deleted successfully`)}catch(o){r.error(`Failed to delete CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as Co}from"commander";import ko from"node:fs";import{encryptEnvVars as _o}from"@phala/dstack-sdk/encrypt-env-vars";var sr=new Co().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{let o=await D(t),n=r.startSpinner(`Fetching current configuration for CVM app_${o}`),s=await te(o);if(n.stop(!0),s||(r.error(`CVM with App ID app_${o} not found`),process.exit(1)),!e.compose){let v=ke(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");e.compose=await B("Enter the path to your Docker Compose file:",v,"file")}let a="";if(e.compose)try{a=ko.readFileSync(e.compose,"utf8")}catch(C){r.error(`Failed to read Docker Compose file: ${C instanceof Error?C.message:String(C)}`),process.exit(1)}await G();let c="";if(e.envFile){let C=[];if(e.envFile)try{C=q([],e.envFile),c=await _o(C,s.encrypted_env_pubkey)}catch(v){r.error(`Failed to read environment file: ${v instanceof Error?v.message:String(v)}`),process.exit(1)}}let u={compose_manifest:{docker_compose_file:a,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${o}`},encrypted_env:c,allow_restart:!0},h=r.startSpinner(`Upgrading CVM app_${o}`),f=await Gt(o,u);f||(h.stop(!1),r.error("Failed to upgrade CVM"),process.exit(1)),h.stop(!0),f.detail&&r.info(`Details: ${f.detail}`),r.break(),r.success(`Your CVM is being upgraded. You can check the dashboard for more details:
114
- ${S}/dashboard/cvms/app_${o}`)}catch(o){r.error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as wo}from"commander";import ye from"inquirer";import U from"chalk";var ir=new wo().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{let o=await D(t),n=await te(o),s=e.vcpu,a=e.memory,c=e.diskSize,u=e.allowRestart;s||(s=(await ye.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.vcpu,filter:p=>parseInt(p)}])).vcpu),a||(a=(await ye.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.memory,filter:p=>parseInt(p)}])).memory),c||(c=(await ye.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.disk_size,filter:p=>parseInt(p)}])).diskSize),u||(u=(await ye.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let h=`Are you sure you want to resize CVM app_${o} with the following changes:
115
- `;if(r.keyValueTable({vCPUs:n.vcpu!==s?`${U.red(n.vcpu)} -> ${U.green(s)}`:n.vcpu,Memory:n.memory!==a?`${U.red(n.memory)} MB -> ${U.green(a)} MB`:n.memory,"Disk Size":n.disk_size!==c?`${U.red(n.disk_size)} GB -> ${U.green(c)} GB`:n.disk_size,"Allow Restart":u?U.green("Yes"):U.red("No")}),!e.yes){let{confirm:v}=await ye.prompt([{type:"confirm",name:"confirm",message:h,default:!1}]);if(!v){r.info("Resize operation cancelled");return}}let f=r.startSpinner(`Resizing CVM with App ID app_${o}`);await Ht(o,s,a,c,u?1:0),f.stop(!0),r.break(),r.success(`Your CVM is being resized. You can check the dashboard for more details:
116
- ${S}/dashboard/cvms/app_${o}`)}catch(o){r.error(`Failed to resize CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});var ar=new So().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(er).addCommand(or).addCommand(nr).addCommand(Yt).addCommand(Zt).addCommand(Jt).addCommand(Xt).addCommand(ir).addCommand(Qt).addCommand(sr);import{Command as To}from"commander";var xo=`version: '3'
104
+ `)}return a.background&&(h.unref(),r.success("Simulator is running in the background")),await Ge(),h}catch(e){throw r.error("Error running simulator:",e),new Error(`Failed to run simulator: ${e}`)}}async function Se(){try{let t=ue(),e=I.platforms[t];if(t==="darwin"||t==="linux"){let o="/tmp/tappd.sock";return A.existsSync(o)?new Promise(n=>{let s=We.createConnection({path:o}).on("connect",()=>{s.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{s.end(),n(!1)},1e3)}):!1}if(t==="win32"){let o="127.0.0.1";return new Promise(s=>{let a=We.createConnection({host:o,port:8090}).on("connect",()=>{a.end(),s(!0)}).on("error",()=>{s(!1)});setTimeout(()=>{a.end(),s(!1)},1e3)})}return!1}catch(t){return r.error("Error checking if simulator is running:",t),!1}}async function $t(){try{let t=ue();if(!await Se())return r.info("Simulator is not running"),!0;r.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?r.success("Simulator stopped successfully"):r.error("Failed to stop simulator"),await G(),e}catch(t){return r.error("Error stopping simulator:",t),!1}}function Kr(){return ue()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function Ge(t){try{let e=Kr(),o=t||e;return await ee(`export DSTACK_SIMULATOR_ENDPOINT=${o}`),r.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${o} for current process`),t}catch(e){throw r.error("Error setting simulator endpoint environment variable:",e),new Error(`Failed to set simulator endpoint: ${e}`)}}async function G(){return await ee("unset DSTACK_SIMULATOR_ENDPOIN"),r.success("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var de=Yr(qr),Pt=".phala-cloud/logs",Xr=".phala-cloud/compose",It=10,T=class{username;image;registry;constructor(e,o,n){this.image=e,this.username=o||"",this.registry=n||""}ensureLogsDir(){let e=Ke.resolve(Pt);K.existsSync(e)||K.mkdirSync(e,{recursive:!0})}getLogFilePath(e,o){let n=new Date().toISOString().replace(/[:.]/g,"-");return Ke.resolve(Pt,`${o||this.image}-${e}-${n}.log`)}getSystemArchitecture(){let e=Jr.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,o,n,s){return new Promise((a,c)=>{let u=Zr(e,o);this.ensureLogsDir();let h=this.getLogFilePath(n,s),f=K.createWriteStream(h,{flags:"a"}),C=[],b=(p,m=!1)=>{let l=p.toString().split(`
105
+ `);f.write(p),l.forEach(g=>{g.trim()&&(C.push(g),C.length>It&&C.shift(),console.clear(),console.log(`Latest ${It} lines (full log at ${h}):`),console.log("-".repeat(50)),C.forEach(y=>{m?console.error(y):console.log(y)}))})};u.stdout.on("data",p=>b(p)),u.stderr.on("data",p=>b(p,!0)),u.on("close",p=>{f.end(),p===0?(console.log(`
106
+ Operation completed. Full log available at: ${h}`),a()):c(new Error(`Process exited with code ${p}. Check log file: ${h}`))}),u.on("error",p=>{f.end(),c(p)})})}setCredentials(e,o){this.username=e,o&&(this.registry=o)}async buildImage(e,o){try{let n=this.getSystemArchitecture(),s=`${this.username}/${this.image}:${o}`,a=r.startSpinner(`Building Docker image ${this.username}/${this.image}:${o}`);B(e);let c=["build","-t",s,"-f",e];return n==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),c.push("--platform","linux/amd64")),c.push("."),await this.spawnProcess("docker",c,"build",this.image),a.stop(!0,`Docker image ${s} built successfully`),!0}catch(n){return r.error(`Failed to build Docker image: ${n instanceof Error?n.message:String(n)}`),!1}}async pushImage(e){try{let o=r.startSpinner(`Pushing Docker image ${e} to Docker Hub`);if(!await L())throw o.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let s=e;return console.log(`Pushing image ${s} to Docker Hub...`),await this.spawnProcess("docker",["push",s],"push",e.replace(/.*\/+(\w+):.*$/g,"$1")),o.stop(!0,`Docker image ${s} pushed successfully`),!0}catch(o){return r.error(`Failed to push Docker image: ${o instanceof Error?o.message:String(o)}`),!1}}async login(e,o,n){try{let s=r.startSpinner(`Logging in to Docker Hub as ${e}`);return await this.checkLogin()?(s.stop(!0,`Logged in as ${e}`),this.setCredentials(e,n),!0):(await Tt("docker",["login",...n?[n]:[],"-u",e,"--password-stdin"],{input:o}),s.stop(!0,"Logged in to Docker Hub successfully"),!0)}catch(s){return r.error(`Failed to login to Docker Hub: ${s instanceof Error?s.message:String(s)}`),!1}}async checkLogin(){try{let{stdout:e}=await Tt("docker",["login"]);return e.includes("Login Succeeded")}catch{return!1}}async buildComposeFile(e,o,n){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let s=n==="eliza"?ct:mt,a=ut.parse({template:s}),c=Xr;K.existsSync(c)||(r.info(`Creating directory: ${c}`),K.mkdirSync(c,{recursive:!0}));let u=[];o&&(u=K.readFileSync(o,"utf-8").split(`
107
+ `).filter(m=>m&&!m.startsWith("#")).map(m=>{let l=m.indexOf("#");return l>0&&(m=m.substring(0,l).trim()),m.trim()}).filter(m=>m.includes("=")).map(m=>{let[l,g]=m.split("=",2),y=l.trim();return(g?g.trim():"")===""?null:`${y}=${y}`}).filter(Boolean));let h=e,C=Hr.compile(a.template,{noEscape:!0})({imageName:h,envVars:u.map(p=>p.replace(/=.*/,"=${"+p.split("=")[0]+"}"))}),b=Ke.join(c,`${e.replace(/.*\/+(\w+):.*$/g,"$1")}-tee-compose.yaml`);return K.writeFileSync(b,C),r.success(`Backup of docker compose file created at: ${b}`),b}async runComposeLocally(e,o){try{let n=r.startSpinner(`Running Docker Compose file at ${e}`);B(e);let s=["-f",e,"up","-d"];return o&&(B(o),s.splice(2,0,"--env-file",o)),await de(`docker compose ${s.join(" ")}`),n.stop(!0,"Docker Compose file running successfully"),!0}catch(n){return r.error(`Failed to run Docker Compose file: ${n instanceof Error?n.message:String(n)}`),!1}}async runSimulator(e,o){try{r.info(`Running TEE simulator with image ${e}`),r.info("Pulling latest simulator image..."),await de(`docker pull ${e}`),r.info("Starting simulator in background...");let{stdout:n}=await de(`docker run -d --name tee-simulator --rm -p ${o}:${o} ${e}`),s=n.trim();return r.success(`TEE simulator running successfully. Container ID: ${s}`),r.break(),r.break(),r.info("Useful commands:"),r.info(`- View logs: docker logs -f ${s}`),r.info(`- Stop simulator: docker stop ${s}`),Ge(`http://localhost:${o}`),!0}catch(n){return r.error(`Failed to run TEE simulator: ${n instanceof Error?n.message:String(n)}`),!1}}async stopSimulator(){try{let e=r.startSpinner("Stopping TEE simulator...");return await de("docker stop tee-simulator"),await G(),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return r.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),!1}}static async listLocalImages(){try{let{stdout:e}=await de('docker images --format "{{.Repository}}:{{.Tag}}"'),n=(await L())?.username;return e.split(`
108
+ `).filter(a=>a&&!a.includes("<none>")).filter(a=>a.includes(`${n}/`)).map(a=>({imageName:a}))}catch(e){return r.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import Dt from"prompts";var At=new Qr().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,o=t.password,n=t.registry;if(!e){r.info("First we need your Docker Hub username to check if you are already logged in.");let u=await Dt({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:h=>h.length>0?!0:"Username cannot be empty"});u.username||(r.error("Username is required"),process.exit(1)),e=u.username}let s=new T("",e,n);if(await s.login(e)){r.success(`${e} is logged in to Docker Hub`);return}if(!o){let u=await Dt({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:h=>h.length>0?!0:"Password cannot be empty"});u.password||(r.error("Password is required"),process.exit(1)),o=u.password}await s.login(e,o,n)||(r.error("Failed to login to Docker Hub"),process.exit(1)),await nt({username:e,registry:n||null}),r.success("Logged in to Docker Hub successfully")}catch(e){r.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as eo}from"commander";import Rt from"node:path";import Ft from"inquirer";import to from"node:fs";var Mt=new eo().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 L();if(e||(r.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:u=>u.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:u=>u.trim()?!0:"Tag is required"}]);t.tag=c.tag}let o=Rt.resolve(process.cwd(),t.file);to.existsSync(o)||(r.info(`Default Dockerfile not found at ${o}`),t.file=await W("Enter the path to your Dockerfile:","Dockerfile","file"));let n=Rt.resolve(process.cwd(),t.file);await new T(t.image,e.username,e.registry).buildImage(n,t.tag)||(r.error("Failed to build Docker image"),process.exit(1)),r.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){r.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ro}from"commander";import oo from"inquirer";var Vt=new ro().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 L();e||(r.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let o=t.image;if(!o){let a=await T.listLocalImages();if(a.length===0&&(r.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!o){let c=Array.from(new Set(a.map(h=>h.imageName))),{selectedImage:u}=await oo.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:c}]);o=u}}await new T("",e.username,e.registry).pushImage(o)||(r.error("Failed to push Docker image"),process.exit(1)),r.success(`Docker image ${o} pushed successfully`)}catch(e){r.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as no}from"commander";import fe from"inquirer";import ge from"node:fs";import xe from"node:path";var Lt=new no().name("generate").description("Generate a Docker Compose file").option("-i, --image <imageName>","Docker image name to use in the compose file (e.g. phala/phala-cloud)").option("-e, --env-file <envFile>","Path to environment variables file").option("-o, --output <output>","Output path for generated docker-compose.yml").option("--template <template>","Template to use for the generated docker-compose.yml").action(async t=>{try{let e=await L();(!e||!e.username)&&(r.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let o=t.image;if(!o){let u=await T.listLocalImages();if(u.length===0&&(r.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!o){let h=Array.from(new Set(u.map(C=>C.imageName))),{selectedImage:f}=await fe.prompt([{type:"list",name:"selectedImage",message:"Select an image to use in the compose file:",choices:h}]);o=f}}let n=t.envFile;if(n)try{B(n)}catch{r.error(`File not found: ${n}`),process.exit(1)}else{let u=xe.join(process.cwd(),".env");if(ge.existsSync(u)){let{useDefault:f}=await fe.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);f&&(n=u)}if(!n){let{envPath:f}=await fe.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:C=>{try{return B(C),!0}catch{return`File not found: ${C}`}}}]);n=f}}let s=t.output;if(!s&&(s=xe.join(process.cwd(),"docker-compose.yml"),ge.existsSync(s))){let{confirmOverwrite:u}=await fe.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${s} already exists. Overwrite?`,default:!1}]);if(!u){let{customPath:h}=await fe.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:xe.join(process.cwd(),"docker-generated-compose.yml")}]);s=h}}let a=new T("",e.username,e.registry);n?r.info(`Generating Docker Compose file for ${o} using env file: ${n}`):r.info(`Generating Docker Compose file for ${o} without env file`);let c=await a.buildComposeFile(o,n,t.template);if(c!==s){let u=xe.dirname(s);ge.existsSync(u)||(r.info(`Creating directory: ${u}`),ge.mkdirSync(u,{recursive:!0})),ge.copyFileSync(c,s)}r.success(`Docker Compose file generated successfully: ${s}`)}catch(e){r.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Nt=new so().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(At).addCommand(Mt).addCommand(Vt).addCommand(Lt);import{Command as co}from"commander";import{Command as io}from"commander";var Ot=new io().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",it).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)||(r.error("Failed to start TEE simulator"),process.exit(1));else if(t.type==="native")if(St()||await xt(),await Se()){r.success("TEE simulator is already running");return}else{let o=Et();r.success("TEE simulator started successfully")}else r.error("Invalid simulator type"),process.exit(1)}catch(e){r.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ao}from"commander";var Ut=new ao().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()||(r.error("Failed to stop TEE simulator"),process.exit(1)):t.type==="native"?await $t()||(r.error("Failed to stop TEE simulator"),process.exit(1)):(r.error("Invalid simulator type"),process.exit(1))}catch(e){r.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var zt=new co().name("simulator").description("TEE simulator commands").addCommand(Ot).addCommand(Ut);import{Command as To}from"commander";import{Command as po}from"commander";import mo from"inquirer";import{z as jt}from"zod";async function Ee(){try{let t=await $.get(E.CVMS(0));return jt.array(Ue).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function $e(t){let o=(await Ee()).find(n=>n.hosted?.app_id===t||`app_${n.hosted?.app_id}`===t);if(!o)r.error(`CVM with App ID app_${t} not detected`),process.exit(1);else return r.success(`CVM with App ID app_${t} detected`),o.hosted?.app_id||""}async function te(t){try{let e=await $.get(E.CVM_BY_APP_ID(t));return ft.parse(e)}catch(e){throw new Error(`Failed to get CVM by App ID: ${e instanceof Error?e.message:String(e)}`)}}async function Te(t){try{let e=await $.post(E.CVM_PUBKEY,t);return dt.parse(e)}catch(e){throw new Error(`Failed to get pubkey from CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Pe(t){try{let e=await $.post(E.CVM_FROM_CONFIGURATION,t);return le.parse(e)}catch(e){throw e instanceof jt.ZodError?(r.error("Schema validation error:",JSON.stringify(e.errors,null,2)),r.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{let e=await $.post(E.CVM_START(t));return le.parse(e)}catch(e){throw new Error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Wt(t){try{let e=await $.post(E.CVM_STOP(t));return le.parse(e)}catch(e){throw new Error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Gt(t){try{let e=await $.post(E.CVM_RESTART(t));return le.parse(e)}catch(e){throw new Error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Kt(t,e){try{let o=await $.put(E.CVM_UPGRADE(t),e);return ht.parse(o)}catch(o){throw new Error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`)}}async function Ht(t){try{return await $.delete(E.CVM_BY_APP_ID(t)),!0}catch(e){throw new Error(`Failed to delete CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Ie(){let t=r.startSpinner("Fetching available CVMs"),e=await Ee();if(t.stop(!0),!e||e.length===0){r.info("No CVMs found for your account");return}let o=e.map(s=>{let a=s.hosted?.app_id||s.hosted?.id,c=s.name||s.hosted?.name,u=s.status||s.hosted?.status;return{name:`${c||"Unnamed"} (${a}) - Status: ${u||"Unknown"}`,value:a}}),{selectedCvm:n}=await mo.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:o}]);return n}async function qt(t){try{let e=await $.get(E.CVM_ATTESTATION(t));try{return bt.parse(e)}catch(o){return r.debug(`Validation error: ${o instanceof Error?o.message:String(o)}`),{is_online:!!e?.is_online,is_public:!!e?.is_public,error:typeof e?.error=="string"?e.error:null,app_certificates:Array.isArray(e?.app_certificates)?e.app_certificates:null,tcb_info:e?.tcb_info||null,compose_file:typeof e?.compose_file=="string"?e.compose_file:null}}}catch(e){throw new Error(`Failed to get attestation information: ${e instanceof Error?e.message:String(e)}`)}}async function Zt(t,e,o,n,s){try{let a={};if(e!==void 0&&(a.vcpu=e),o!==void 0&&(a.memory=o),n!==void 0&&(a.disk_size=n),s!==void 0&&(a.allow_restart=s),Object.keys(a).length===0)throw new Error("At least one resource parameter must be provided");return await $.patch(E.CVM_RESIZE(t),a),!0}catch(a){throw new Error(`Failed to resize CVM: ${a instanceof Error?a.message:String(a)}`)}}import He from"chalk";var Yt=new po().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=r.startSpinner("Fetching CVMs"),o=await Ee();if(e.stop(!0),!o||o.length===0){r.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(o,null,2));return}for(let n of o)r.keyValueTable({Name:n.name,"App ID":`app_${n.hosted.app_id}`,Status:n.status==="running"?He.green(n.status):n.status==="stopped"?He.red(n.status):He.yellow(n.status),"Node Info URL":n.hosted.app_url,"App URL":`${S}/dashboard/cvms/app_${n.hosted.app_id}`}),r.break();r.success(`Found ${o.length} CVMs`),r.break(),r.info(`Go to ${S}/dashboard/ to view your CVMs`)}catch(e){r.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as lo}from"commander";import qe from"chalk";async function D(t){if(!t){let e=await Ie();return e||void 0}return await $e(t)}var Jt=new lo().name("get").description("Get details of a CVM").argument("[app-id]","App ID of the CVM (optional)").option("-j, --json","Output in JSON format").action(async(t,e)=>{try{let o=await D(t),n=r.startSpinner(`Fetching CVM with App ID app_${o}`),s=await te(o);if(n.stop(!0),r.break(),s||(r.error(`CVM with App ID app_${o} not found`),process.exit(1)),e.json){console.log(JSON.stringify(s,null,2));return}r.keyValueTable({Name:s.name,"App ID":`app_${s.app_id}`,Status:s.status==="running"?qe.green(s.status):s.status==="stopped"?qe.red(s.status):qe.yellow(s.status),vCPU:s.vcpu,Memory:`${s.memory} MB`,"Disk Size":`${s.disk_size} GB`,"Dstack Image":s.base_image,"App URL":`${S}/dashboard/cvms/app_${s.app_id}`})}catch(o){r.error(`Failed to get CVM details: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as uo}from"commander";var Xt=new uo().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{let e=await D(t),o=r.startSpinner(`Starting CVM with App ID app_${e}`),n=await Bt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being started. You can check the dashboard for more details:
109
+ ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as fo}from"commander";var Qt=new fo().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{let e=await D(t),o=r.startSpinner(`Stopping CVM with App ID app_${e}`),n=await Wt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being stopped. You can check the dashboard for more details:
110
+ ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as go}from"commander";var er=new go().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{let e=await D(t),o=r.startSpinner(`Restarting CVM with App ID app_${e}`),n=await Gt(e);o.stop(!0),r.break();let s={"CVM ID":n.id,Name:n.name,Status:n.status,"App ID":`app_${n.app_id}`,"App URL":n.app_url?n.app_url:`${S}/dashboard/cvms/app_${n.app_id}`};r.keyValueTable(s,{borderStyle:"rounded"}),r.break(),r.success(`Your CVM is being restarted. You can check the dashboard for more details:
111
+ ${S}/dashboard/cvms/app_${n.app_id}`)}catch(e){r.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as ho}from"commander";import De from"chalk";var tr=new ho().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{let o;if(t)o=await $e(t);else{r.info("No CVM specified, fetching available CVMs...");let s=await Ie();if(!s)return;o=s}let n=r.startSpinner(`Fetching attestation information for CVM app_${o}...`);try{let s=await qt(o);if(n.stop(!0),!s||Object.keys(s).length===0){r.info("No attestation information found");return}if(e?.json){r.info(JSON.stringify(s,null,2));return}r.success("Attestation Summary:");let a={Status:s.is_online?De.green("Online"):De.red("Offline"),"Public Access":s.is_public?De.green("Enabled"):De.yellow("Disabled"),Error:s.error||"None",Certificates:`${s.app_certificates?.length||0} found`};if(r.keyValueTable(a,{borderStyle:"rounded"}),s.app_certificates&&s.app_certificates.length>0&&s.app_certificates.forEach((c,u)=>{r.break(),r.success(`Certificate #${u+1} (${c.position_in_chain===0?"End Entity":"CA"}):`);let h={Subject:`${c.subject.common_name||"Unknown"}${c.subject.organization?` (${c.subject.organization})`:""}`,Issuer:`${c.issuer.common_name||"Unknown"}${c.issuer.organization?` (${c.issuer.organization})`:""}`,"Serial Number":c.serial_number,Validity:`${new Date(c.not_before).toLocaleString()} to ${new Date(c.not_after).toLocaleString()}`,Fingerprint:c.fingerprint,"Signature Algorithm":c.signature_algorithm,"Is CA":c.is_ca?"Yes":"No","Position in Chain":c.position_in_chain};r.keyValueTable(h,{borderStyle:"rounded"})}),s.tcb_info){r.break(),r.success("Trusted Computing Base (TCB) Information:");let c={Mrtd:s.tcb_info.mrtd,"Rootfs Hash":s.tcb_info.rootfs_hash,Rtmr0:s.tcb_info.rtmr0,Rtmr1:s.tcb_info.rtmr1,Rtmr2:s.tcb_info.rtmr2,Rtmr3:s.tcb_info.rtmr3,"Event Log Entries":`${s.tcb_info.event_log.length} entries`};if(r.keyValueTable(c,{borderStyle:"rounded"}),s.tcb_info.event_log&&s.tcb_info.event_log.length>0){r.break(),r.success("Event Log (Showing entries to reproduce RTMR3):");let u=5,h=s.tcb_info.event_log.filter(f=>f.event!==null&&f.event!=="").map(f=>({Event:f.event,IMR:f.imr.toString(),"Event Type":f.event_type.toString(),Payload:f.event_payload}));r.table(h,[{key:"Event",header:"Event",minWidth:8},{key:"IMR",header:"IMR",minWidth:3},{key:"Event Type",header:"Type",minWidth:8},{key:"Payload",header:"Payload",minWidth:25}]),s.tcb_info.event_log.length>u&&r.info("To see all full attestation data, use --json"),r.break(),r.success("To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/")}}}catch(s){throw n.stop(!1),s}}catch(o){r.error(`Failed to get attestation information: ${o instanceof Error?o.message:String(o)}`)}});import{Command as vo}from"commander";import{z as yo}from"zod";async function Ze(){try{let t=await $.get(E.TEEPODS);return yt.parse(t).nodes}catch(t){throw new Error(`Failed to get TEEPods: ${t instanceof Error?t.message:String(t)}`)}}async function rr(t){try{let o=(await Ze()).find(s=>s.teepod_id===Number(t));if(o&&o.images&&o.images.length>0)return o.images;let n=await $.get(E.TEEPOD_IMAGES(t));return yo.array(ze).parse(n)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}import{encryptEnvVars as Co}from"@phala/dstack-sdk/encrypt-env-vars";import or from"node:fs";import ko from"node:path";import he from"inquirer";import bo from"node:fs";var H=(t,e)=>{let o={};if(t){for(let n of t)if(n.includes("=")){let[s,a]=n.split("=");s&&a&&(o[s]=a)}}if(e){let n=bo.readFileSync(e,"utf8");for(let s of n.split(`
112
+ `))if(!(!s.trim()||s.trim().startsWith("#"))&&s.includes("=")){let[a,...c]=s.split("="),u=c.join("="),h=u.search(/\s+#/);h!==-1&&(u=u.substring(0,h).trim()),a&&u&&(o[a.trim()]=u.trim())}}return Object.entries(o).map(([n,s])=>({key:n,value:s}))};var nr=new vo().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(ie)).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",at).option("--image <image>","Version of dstack image to use",we).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=_e(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");t.compose=await W("Enter the path to your Docker Compose file:",l,"file")}let e=ko.resolve(t.compose);or.existsSync(e)||(r.error(`Docker Compose file not found: ${e}`),process.exit(1));let o=or.readFileSync(e,"utf8");await G();let n=[];if(t.envFile)try{n=H([],t.envFile)}catch(m){r.error(`Failed to read environment file: ${m instanceof Error?m.message:String(m)}`),process.exit(1)}else if(!t.skipEnv){let{shouldSkip:m}=await he.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!0}]);if(m)r.info("Skipping environment variable prompt");else{let l=await W("Enter the path to your environment file:",".env","file");n=H([],l)}}let s=[];if(t.vcpu===String(ie)&&s.push({type:"input",name:"vcpu",message:`Enter number of vCPUs (default: ${ie}):`,default:String(ie),validate:m=>{let l=parseInt(m);return isNaN(l)||l<=0?"Please enter a valid positive number":!0}}),t.memory===String(ae)&&s.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)&&s.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}}),s.length>0){let m=await he.prompt(s);m.vcpu&&(t.vcpu=m.vcpu),m.memory&&(t.memory=m.memory),m.diskSize&&(t.diskSize=m.diskSize)}if(!t.teepodId){let m=r.startSpinner("Fetching available TEEPods"),l=await Ze();m.stop(!0),l.length===0&&(r.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:g}=await he.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:l.map(d=>({name:`${d.name}`,value:d.teepod_id}))}]),y=l.find(d=>d.teepod_id===g);y||(r.error("Failed to find selected TEEPod"),process.exit(1)),r.info(`Selected TEEPod: ${y.name}`),t.teepodId=y.teepod_id}if(!t.image){let l=(await rr(t.teepodId)).map(y=>({name:`${y.name}`,value:y.name})),{selectedImage:g}=await he.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:l}]);t.image=g.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:o,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=r.startSpinner("Getting public key from CVM"),u=await Te(a);c.stop(!0),u||(r.error("Failed to get public key from CVM"),process.exit(1));let h=r.startSpinner("Encrypting environment variables"),f=await Co(n,u.app_env_encrypt_pubkey);h.stop(!0),t.debug&&(r.debug("Public key:",u.app_env_encrypt_pubkey),r.debug("Encrypted environment variables:",f),r.debug("Environment variables:",JSON.stringify(n)));let C=r.startSpinner("Creating CVM"),b=await Pe({...a,encrypted_env:f,app_env_encrypt_pubkey:u.app_env_encrypt_pubkey,app_id_salt:u.app_id_salt});C.stop(!0),b||(r.error("Failed to create CVM"),process.exit(1)),r.success("CVM created successfully"),r.break();let p={"CVM ID":b.id,Name:b.name,Status:b.status,"App ID":`app_${b.app_id}`,"App URL":b.app_url?b.app_url:`${S}/dashboard/cvms/app_${b.app_id}`};r.keyValueTable(p,{borderStyle:"rounded"}),r.info(""),r.success(`Your CVM is being created. You can check its status with:
113
+ phala cvms get app_${b.app_id}`)}catch(e){r.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as wo}from"commander";import _o from"inquirer";var sr=new wo().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{let o=await D(t);if(!e.force){let{confirm:a}=await _o.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID app_${o}? This action cannot be undone.`,default:!1}]);if(!a){r.info("Deletion cancelled");return}}let n=r.startSpinner(`Deleting CVM app_${o}`),s=await Ht(o);n.stop(!0),s||(r.error(`Failed to delete CVM app_${o}`),process.exit(1)),r.success(`CVM app_${o} deleted successfully`)}catch(o){r.error(`Failed to delete CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as So}from"commander";import xo from"node:fs";import{encryptEnvVars as Eo}from"@phala/dstack-sdk/encrypt-env-vars";var ir=new So().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{let o=await D(t),n=r.startSpinner(`Fetching current configuration for CVM app_${o}`),s=await te(o);if(n.stop(!0),s||(r.error(`CVM with App ID app_${o} not found`),process.exit(1)),!e.compose){let b=_e(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");e.compose=await W("Enter the path to your Docker Compose file:",b,"file")}let a="";if(e.compose)try{a=xo.readFileSync(e.compose,"utf8")}catch(C){r.error(`Failed to read Docker Compose file: ${C instanceof Error?C.message:String(C)}`),process.exit(1)}await G();let c="";if(e.envFile){let C=[];if(e.envFile)try{C=H([],e.envFile),c=await Eo(C,s.encrypted_env_pubkey)}catch(b){r.error(`Failed to read environment file: ${b instanceof Error?b.message:String(b)}`),process.exit(1)}}let u={compose_manifest:{docker_compose_file:a,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${o}`},encrypted_env:c,allow_restart:!0},h=r.startSpinner(`Upgrading CVM app_${o}`),f=await Kt(o,u);f||(h.stop(!1),r.error("Failed to upgrade CVM"),process.exit(1)),h.stop(!0),f.detail&&r.info(`Details: ${f.detail}`),r.break(),r.success(`Your CVM is being upgraded. You can check the dashboard for more details:
114
+ ${S}/dashboard/cvms/app_${o}`)}catch(o){r.error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as $o}from"commander";import ye from"inquirer";import U from"chalk";var ar=new $o().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{let o=await D(t),n=await te(o),s=e.vcpu,a=e.memory,c=e.diskSize,u=e.allowRestart;s||(s=(await ye.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.vcpu,filter:p=>parseInt(p)}])).vcpu),a||(a=(await ye.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.memory,filter:p=>parseInt(p)}])).memory),c||(c=(await ye.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:p=>{let m=parseInt(p);return isNaN(m)||m<0?"Please enter a valid non-negative number":!0},default:n.disk_size,filter:p=>parseInt(p)}])).diskSize),u||(u=(await ye.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let h=`Are you sure you want to resize CVM app_${o} with the following changes:
115
+ `;if(r.keyValueTable({vCPUs:n.vcpu!==s?`${U.red(n.vcpu)} -> ${U.green(s)}`:n.vcpu,Memory:n.memory!==a?`${U.red(n.memory)} MB -> ${U.green(a)} MB`:n.memory,"Disk Size":n.disk_size!==c?`${U.red(n.disk_size)} GB -> ${U.green(c)} GB`:n.disk_size,"Allow Restart":u?U.green("Yes"):U.red("No")}),!e.yes){let{confirm:b}=await ye.prompt([{type:"confirm",name:"confirm",message:h,default:!1}]);if(!b){r.info("Resize operation cancelled");return}}let f=r.startSpinner(`Resizing CVM with App ID app_${o}`);await Zt(o,s,a,c,u?1:0),f.stop(!0),r.break(),r.success(`Your CVM is being resized. You can check the dashboard for more details:
116
+ ${S}/dashboard/cvms/app_${o}`)}catch(o){r.error(`Failed to resize CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});var cr=new To().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(tr).addCommand(nr).addCommand(sr).addCommand(Jt).addCommand(Yt).addCommand(Xt).addCommand(Qt).addCommand(ar).addCommand(er).addCommand(ir);import{Command as Po}from"commander";import{execSync as be}from"node:child_process";import*as pr from"node:os";function Io(t){let e=pr.platform();try{switch(e){case"darwin":be(`open "${t}"`);break;case"win32":be(`start "" "${t}"`);break;case"linux":try{be(`xdg-open "${t}"`)}catch{try{be(`gnome-open "${t}"`)}catch{be(`kde-open "${t}"`)}}break;default:throw new Error(`Unsupported platform: ${e}`)}r.success(`Opened URL in your default browser: ${t}`)}catch(o){r.error(`Failed to open URL: ${o instanceof Error?o.message:String(o)}`),r.info(`Please manually open this URL in your browser: ${t}`)}}function mr(t){return new Promise(e=>setTimeout(e,t))}var lr=new Po().name("join").alias("free").description("Join Phala Cloud! Get an account and deploy a CVM for FREE").action(async()=>{try{let t="https://cloud.phala.network/register?invite=PHALACLI",e=r.startSpinner("Brewing a fresh cup of TEE \u{1F375}");await mr(2e3),e.stop(!0),r.break(),r.break(),console.log(Ce),r.info("TEE is served! Opening Phala Cloud registration page..."),await mr(1e3),r.break(),Io(t)}catch(t){r.error(`Error: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Ro}from"commander";var Do=`version: '3'
117
117
  services:
118
118
  jupyter:
119
119
  image: quay.io/jupyter/base-notebook
@@ -125,13 +125,13 @@ services:
125
125
  - GRANT_SUDO=yes
126
126
  user: root
127
127
  command: "start-notebook.sh --NotebookApp.token=\${TOKEN}"
128
- `,Eo=`version: '3'
128
+ `,Ao=`version: '3'
129
129
  services:
130
130
  httpbin:
131
131
  image: kennethreitz/httpbin:latest
132
132
  ports:
133
133
  - "80:80"
134
- `,cr={jupyter:{compose:xo,name:"Jupyter Notebook"},httpbin:{compose:Eo,name:"HTTPBin"}};import{encryptEnvVars as $o}from"@phala/dstack-sdk/encrypt-env-vars";import mr from"inquirer";import Po from"node:crypto";var pr=new To().name("demo").description("Demo commands to launch a demo on Phala Cloud").action(async()=>{try{await Y()||(r.error("You need to be logged in to use the demo command"),r.info("Please login with: phala auth login"),process.exit(1));try{let l=r.startSpinner("Verifying your credentials"),g=await j();l.stop(!0),r.success(`Logged in as ${g.username}`)}catch{r.error("Authentication failed. Your API key may be invalid or expired."),r.info("Please set a new API key with: phala auth login"),process.exit(1)}let e=Object.values(cr);e.length===0&&(r.error("No template files found in the templates directory"),process.exit(1));let{selectedTemplate:o}=await mr.prompt([{type:"list",name:"selectedTemplate",message:"Select a template to deploy:",choices:e.map(l=>({name:l.name,value:l}))}]),n=o.compose;r.success(`Selected template: ${o.name}`);let s=Po.randomBytes(16).toString("hex"),a=q([`TOKEN=${s}`],""),{cvmName:c}=await mr.prompt([{type:"input",name:"cvmName",message:"Enter a name for your CVM:",default:`${o.name.replace(" ","-")}`,validate:l=>l.trim()?!0:"CVM name is required"}]);r.info("Preparing to deploy your CVM...");let u={teepod_id:3,name:c,image:Ce,vcpu:2,memory:2048,disk_size:20,compose_manifest:{docker_compose_file:n,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:c,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},h=r.startSpinner("Preparing CVM configuration"),f=await Ee(u);h.stop(!0),f||(r.error("Failed to prepare CVM configuration"),process.exit(1));let C=await $o(a,f.app_env_encrypt_pubkey);r.info("Public key:",f.app_env_encrypt_pubkey),r.info("Encrypted environment variables:",C);let v=r.startSpinner("Creating your demo CVM"),p=await Te({...u,encrypted_env:C,app_env_encrypt_pubkey:f.app_env_encrypt_pubkey,app_id_salt:f.app_id_salt});v.stop(!0),p||(r.error("Failed to create demo CVM"),process.exit(1)),r.success("Demo CVM created successfully! \u{1F389}"),r.break();let m={"CVM ID":p.id,Name:p.name,Status:p.status,"App ID":`app_${p.app_id}`,"App URL":p.app_url?p.app_url:`${S}/dashboard/cvms/app_${p.app_id}`,Template:o.name,Resources:"2 vCPUs, 2GB RAM, 20GB Storage"};o.name.includes("Jupyter Notebook")&&(m["Jupyter Token"]=s,m["Access Instructions"]="Access your Jupyter notebook using the token above. Go to 'Network' tab to see the public URL."),r.keyValueTable(m,{borderStyle:"rounded"}),r.info(""),r.success(`Your demo is being created. You can check its status with:
135
- phala cvms get app_${p.app_id}`)}catch(t){r.error(`Failed to launch demo: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function Do(){new Io().name("phala").alias("pha").description(`${Xe}
136
- Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("v1.0.0").addCommand(_t).addCommand(ar).addCommand(Lt).addCommand(Ut).addCommand(pr).parse(process.argv)}Do().catch(t=>{r.error("An error occurred:",t),process.exit(1)});
134
+ `,ur={jupyter:{compose:Do,name:"Jupyter Notebook"},httpbin:{compose:Ao,name:"HTTPBin"}};import{encryptEnvVars as Fo}from"@phala/dstack-sdk/encrypt-env-vars";import dr from"inquirer";import Mo from"node:crypto";var fr=new Ro().name("demo").description("Demo commands to launch a demo on Phala Cloud").action(async()=>{try{await Y()||(r.error("You need to be logged in to use the demo command"),r.info("Please login with: phala auth login"),process.exit(1));try{let l=r.startSpinner("Verifying your credentials"),g=await j();l.stop(!0),r.success(`Logged in as ${g.username}`)}catch{r.error("Authentication failed. Your API key may be invalid or expired."),r.info("Please set a new API key with: phala auth login"),process.exit(1)}let e=Object.values(ur);e.length===0&&(r.error("No template files found in the templates directory"),process.exit(1));let{selectedTemplate:o}=await dr.prompt([{type:"list",name:"selectedTemplate",message:"Select a template to deploy:",choices:e.map(l=>({name:l.name,value:l}))}]),n=o.compose;r.success(`Selected template: ${o.name}`);let s=Mo.randomBytes(16).toString("hex"),a=H([`TOKEN=${s}`],""),{cvmName:c}=await dr.prompt([{type:"input",name:"cvmName",message:"Enter a name for your CVM:",default:`${o.name.replace(" ","-")}`,validate:l=>l.trim()?!0:"CVM name is required"}]);r.info("Preparing to deploy your CVM...");let u={teepod_id:3,name:c,image:we,vcpu:2,memory:2048,disk_size:20,compose_manifest:{docker_compose_file:n,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:c,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},h=r.startSpinner("Preparing CVM configuration"),f=await Te(u);h.stop(!0),f||(r.error("Failed to prepare CVM configuration"),process.exit(1));let C=await Fo(a,f.app_env_encrypt_pubkey);r.debug("Public key:",f.app_env_encrypt_pubkey),r.debug("Encrypted environment variables:",C);let b=r.startSpinner("Creating your demo CVM"),p=await Pe({...u,encrypted_env:C,app_env_encrypt_pubkey:f.app_env_encrypt_pubkey,app_id_salt:f.app_id_salt});b.stop(!0),p||(r.error("Failed to create demo CVM"),process.exit(1)),r.success("Demo CVM created successfully! \u{1F389}"),r.break();let m={"CVM ID":p.id,Name:p.name,Status:p.status,"App ID":`app_${p.app_id}`,"App URL":p.app_url?p.app_url:`${S}/dashboard/cvms/app_${p.app_id}`,Template:o.name,Resources:"2 vCPUs, 2GB RAM, 20GB Storage"};o.name.includes("Jupyter Notebook")&&(m["Jupyter Token"]=s,m["Access Instructions"]="Access your Jupyter notebook using the token above. Go to 'Network' tab to see the public URL."),r.keyValueTable(m,{borderStyle:"rounded"}),r.break(),r.success(`Your demo is being created. You can check its status with:
135
+ phala cvms get app_${p.app_id}`)}catch(t){r.error(`Failed to launch demo: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function Lo(){new Vo().name("phala").alias("pha").description(`${Ce}
136
+ Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("v1.0.2").addCommand(_t).addCommand(cr).addCommand(Nt).addCommand(zt).addCommand(fr).addCommand(lr).parse(process.argv)}Lo().catch(t=>{r.error("An error occurred:",t),process.exit(1)});
137
137
  //# sourceMappingURL=index.js.map