phala 1.0.16 → 1.0.18
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 +54 -6
- package/dist/api/index.d.ts +374 -20
- package/dist/api/index.js +1 -1
- package/dist/chunk-6GN3UXCF.js +58 -0
- package/dist/chunk-6GN3UXCF.js.map +1 -0
- package/dist/index.js +25 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4IVSVXD3.js +0 -58
- package/dist/chunk-4IVSVXD3.js.map +0 -1
package/dist/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import{$ as
|
2
|
+
import{$ as Z,O as A,P as ke,Q as q,R as V,S as J,U as Q,V as we,W as be,X as Se,Y as _e,Z as Ee,a as e,aa as $e,b as ie,ba as De,c as W,ca as xe,d as U,da as Ie,e as ne,ea as N,f as _,g as h,h as he,i as ae,j as se,k as me,l as O,m as ye,n as ve,q as Ce}from"./chunk-6GN3UXCF.js";import{Command as Sr}from"commander";import Ae from"chalk";var Pe=Ae.hex("#cdfa50"),X=Pe(`
|
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 @@ import{$ as De,L as A,M as ve,N as W,O as V,P as q,R as J,S as Ce,T as ke,U as w
|
|
21
21
|
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
22
22
|
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
23
23
|
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
24
|
-
`)
|
24
|
+
`),$r=Pe(`
|
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,22 +43,25 @@ import{$ as De,L as A,M as ve,N as W,O as V,P as q,R as J,S as Ce,T as ke,U as w
|
|
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
|
-
`),
|
46
|
+
`),Dr=Ae.cyan("PHALA TEE CLOUD CLI");import{Command as At}from"commander";import{Command as $t}from"commander";import Dt from"prompts";var Fe=new $t().name("login").description("Set the API key for authentication").argument("[api-key]","Phala Cloud API key to set").action(async o=>{try{let t;if(!o)o=(await Dt({type:"password",name:"apiKey",message:"Enter your API key:",validate:async i=>{if(i.length===0)return"API key cannot be empty";try{if(await ie(i),t=await A(),!t.username)return await U(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(await ie(o),t=await A(),!t.username)return await U(),"Invalid API key";e.success(`Welcome ${t.username}! API key validated and saved successfully`),e.break(),e.info(`Open in Web UI at ${h}/dashboard/`)}catch(t){e.error(`Failed to set API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as xt}from"commander";var Te=new xt().name("logout").description("Remove the stored API key").action(async()=>{try{await U(),e.success("API key removed successfully")}catch(o){e.error(`Failed to remove API key: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as It}from"commander";var Me=new It().name("status").description("Check authentication status").option("-j, --json","Output in JSON format").option("-d, --debug","Enable debug output").action(async o=>{try{o.debug&&(process.env.DEBUG="true");let t=await W();if(!t){e.warn('Not authenticated. Please set an API key with "phala auth login"');return}e.debug(`Using API key: ${t.substring(0,5)}...`);let r=e.startSpinner("Checking authentication status");try{let i=await A();if(r.stop(!0),o.json){console.log(JSON.stringify(i,null,2));return}e.break(),e.success(`Authenticated as ${i.username}`);let n={Username:i.username,Email:i.email,Role:i.role,Team:`${i.team_name} (${i.team_tier})`,Credits:`$${(i.credits+i.granted_credits).toFixed(2)}`};i.trial_ended_at&&(n["Trial Ended At"]=i.trial_ended_at),e.keyValueTable(n,{borderStyle:"rounded"})}catch(i){r.stop(!1),e.error("Authentication failed. Your API key may be invalid or expired."),e.info('Please set a new API key with "phala auth login"'),o.debug&&e.debug(`Error details: ${i instanceof Error?i.message:String(i)}`)}}catch(t){e.error(`Failed to check authentication status: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var Ve=new At().name("auth").description("Authenticate with Phala Cloud").addCommand(Fe).addCommand(Te).addCommand(Me);import{Command as Ht}from"commander";import{Command as Ot}from"commander";import{execa as Mt}from"execa";import E from"node:fs";import K from"node:path";import Vt from"handlebars";import{exec as Nt,spawn as Rt}from"node:child_process";import{promisify as Lt}from"node:util";import Oe from"node:os";import Pt from"inquirer";import ce from"node:fs";import pe from"node:path";function P(o,t=process.cwd()){let r=pe.resolve(t,o);if(!ce.existsSync(r))throw new Error(`File not found at ${r}`);return!0}async function F(o,t,r="file",i=process.cwd()){return(await Pt.prompt([{type:"input",name:r,message:o,default:t,validate:m=>{let a=pe.resolve(i,m);return ce.existsSync(a)?!0:`File not found at ${a}`}}]))[r]}function ee(o,t){for(let r of o){let i=pe.join(process.cwd(),r);if(ce.existsSync(i))return t?e.info(t.replace("{path}",i)):e.info(`File detected: ${i}`),r}}import*as b from"node:fs";import*as D from"node:path";import*as R from"node:os";import{execSync as L,spawn as Ft}from"node:child_process";import*as le from"node:net";var C={version:"0.1.4",baseUrl:"https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4",installDir:D.join(R.homedir(),".phala-cloud","tappd-simulator"),defaultLogPath:D.join(R.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 Ne(){try{if(!b.existsSync(C.installDir))return!1;let o=R.platform();if(!C.platforms[o])throw new Error(`Unsupported platform: ${o}`);let t=D.join(C.installDir,C.platforms[o].extractedFolder);if(!b.existsSync(t))return!1;let i=D.join(t,o==="win32"?"tappd-simulator.exe":"tappd-simulator");return b.existsSync(i)}catch(o){return e.error("Error checking if simulator is installed:",o),!1}}function z(){let o=R.platform();if(!C.platforms[o])throw new Error(`Unsupported platform: ${o}. Only darwin, linux, and win32 are supported.`);return o}async function Re(o){let t=r=>{e.info(r),o&&o(r)};try{let r=z(),i=C.platforms[r];b.existsSync(C.installDir)||(e.info(`Creating installation directory at ${C.installDir}`),b.mkdirSync(C.installDir,{recursive:!0})),process.chdir(C.installDir);let n=`${C.baseUrl}/${i.filename}`;e.info(`Downloading simulator from ${n}`),L(`wget ${n}`,{stdio:"inherit"}),e.info(`Extracting ${i.filename}`),L(`tar -xvf ${i.filename}`,{stdio:"inherit"}),e.success("Simulator installation completed successfully")}catch(r){throw e.error("Error installing simulator:",r),new Error(`Failed to install simulator: ${r}`)}}async function Le(o={}){try{let t=z(),r=C.platforms[t],i=D.join(C.installDir,r.extractedFolder);process.chdir(i);let n=t==="win32"?"tappd-simulator.exe":"./tappd-simulator",m={background:o.background??!0,logToFile:o.logToFile??!0,logFilePath:o.logFilePath??C.defaultLogPath};if(m.logToFile){let s=D.dirname(m.logFilePath);b.existsSync(s)||b.mkdirSync(s,{recursive:!0}),e.info(`Simulator logs will be written to: ${m.logFilePath}`)}e.info(`Starting simulator with: ${n} -l ${r.socketArg}`);let a="inherit",c=null;m.logToFile&&(c=b.createWriteStream(m.logFilePath,{flags:"a"}),a=["ignore",c,c]);let l=Ft(n,["-l",r.socketArg],{stdio:a,shell:t==="win32",detached:m.background});if(c){let s=new Date().toISOString();c.write(`
|
47
47
|
[${s}] Simulator started
|
48
|
-
`)}return m.background&&(
|
49
|
-
`);s.write(p);for(let
|
50
|
-
Operation completed. Full log available at: ${
|
51
|
-
`).filter(u=>u&&!u.startsWith("#")).map(u=>{let y=u.indexOf("#");return y>0&&(u=u.substring(0,y).trim()),u.trim()}).filter(u=>u.includes("=")).map(u=>{let[y,
|
52
|
-
`).filter(m=>m&&!m.includes("<none>")).filter(m=>m.includes(`${o}/`)).map(m=>({imageName:m}))}catch(t){return e.error(`Failed to list local Docker images: ${t instanceof Error?t.message:String(t)}`),[]}}};import Oe from"prompts";var ze=new Ft().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 i=>{try{let t=i.username,r=i.password,o=i.registry;if(!t){e.info("First we need your Docker Hub username to check if you are already logged in.");let c=await Oe({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:d=>d.length>0?!0:"Username cannot be empty"});c.username||(e.error("Username is required"),process.exit(1)),t=c.username}let n=new v("",t,o);if(await n.login(t)){e.success(`${t} is logged in to Docker Hub`),await ie({username:t,registry:o||null});return}if(!r){let c=await Oe({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:d=>d.length>0?!0:"Password cannot be empty"});c.password||(e.error("Password is required"),process.exit(1)),r=c.password}await n.login(t,r,o)||(e.error("Failed to login to Docker Hub"),process.exit(1)),await ie({username:t,registry:o||null}),e.success("Logged in to Docker Hub successfully")}catch(t){e.error(`Failed to login to Docker Hub: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Tt}from"commander";import je from"node:path";import Ke from"inquirer";import Mt from"node:fs";var Be=new Tt().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 i=>{try{let t=await E();if(t||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!i.image){let a=await Ke.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:c=>c.trim()?!0:"Image name is required"}]);i.image=a.image}if(!i.tag){let a=await Ke.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:c=>c.trim()?!0:"Tag is required"}]);i.tag=a.tag}let r=je.resolve(process.cwd(),i.file);Mt.existsSync(r)||(e.info(`Default Dockerfile not found at ${r}`),i.file=await F("Enter the path to your Dockerfile:","Dockerfile","file"));let o=je.resolve(process.cwd(),i.file);await new v(i.image,t.username,t.registry).buildImage(o,i.tag)||(e.error("Failed to build Docker image"),process.exit(1)),e.success(`Docker image ${t.username}/${i.image}:${i.tag} built successfully`)}catch(t){e.error(`Failed to build Docker image: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Vt}from"commander";import Rt from"inquirer";var Ge=new Vt().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Full image name (e.g. username/image:tag)").action(async i=>{try{let t=await E();t||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let r=i.image;if(!r){let m=await v.listLocalImages();if(m.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let a=Array.from(new Set(m.map(d=>d.imageName))),{selectedImage:c}=await Rt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:a}]);r=c}}await new v("",t.username,t.registry).pushImage(r)||(e.error("Failed to push Docker image"),process.exit(1)),e.success(`Docker image ${r} pushed successfully`)}catch(t){e.error(`Failed to push Docker image: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Nt}from"commander";import K from"inquirer";import B from"node:fs";import te from"node:path";var He=new Nt().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 i=>{try{let t=await E();(!t||!t.username)&&(e.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let r=i.image;if(!r){let c=await v.listLocalImages();if(c.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let d=Array.from(new Set(c.map(f=>f.imageName))),{selectedImage:s}=await K.prompt([{type:"list",name:"selectedImage",message:"Select an image to use in the compose file:",choices:d}]);r=s}}let o=i.envFile;if(o)try{P(o)}catch{e.error(`File not found: ${o}`),process.exit(1)}else{let c=te.join(process.cwd(),".env");if(B.existsSync(c)){let{useDefault:s}=await K.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);s&&(o=c)}if(!o){let{envPath:s}=await K.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:f=>{try{return P(f),!0}catch{return`File not found: ${f}`}}}]);o=s}}let n=i.output;if(!n&&(n=te.join(process.cwd(),"docker-compose.yml"),B.existsSync(n))){let{confirmOverwrite:c}=await K.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${n} already exists. Overwrite?`,default:!1}]);if(!c){let{customPath:d}=await K.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:te.join(process.cwd(),"docker-generated-compose.yml")}]);n=d}}let m=new v("",t.username,t.registry);o?e.info(`Generating Docker Compose file for ${r} using env file: ${o}`):e.info(`Generating Docker Compose file for ${r} without env file`);let a=await m.buildComposeFile(r,o,i.template);if(a!==n){let c=te.dirname(n);B.existsSync(c)||(e.info(`Creating directory: ${c}`),B.mkdirSync(c,{recursive:!0})),B.copyFileSync(a,n)}e.success(`Docker Compose file generated successfully: ${n}`)}catch(t){e.error(`Failed to generate Docker Compose file: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var Ye=new Lt().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(ze).addCommand(Be).addCommand(Ge).addCommand(He);import{Command as zt}from"commander";import{Command as Ut}from"commander";var We=new Ut().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",fe).option("-p, --port <port>","Simulator port (default: 8090)","8090").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async i=>{try{if(i.type==="docker")await new v("").runSimulator(i.image,i.port)||(e.error("Failed to start TEE simulator"),process.exit(1));else if(i.type==="native")if(Te()||await Me(),await ee()){e.success("TEE simulator is already running");return}else{let r=Ve();e.success("TEE simulator started successfully")}else e.error("Invalid simulator type"),process.exit(1)}catch(t){e.error(`Failed to start TEE simulator: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Ot}from"commander";var qe=new Ot().name("stop").description("Stop the TEE simulator").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async i=>{try{i.type==="docker"?await new v("").stopSimulator()||(e.error("Failed to stop TEE simulator"),process.exit(1)):i.type==="native"?await Re()||(e.error("Failed to stop TEE simulator"),process.exit(1)):(e.error("Invalid simulator type"),process.exit(1))}catch(t){e.error(`Failed to stop TEE simulator: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var Je=new zt().name("simulator").description("TEE simulator commands").addCommand(We).addCommand(qe);import{Command as or}from"commander";import{Command as jt}from"commander";import de from"chalk";var Qe=new jt().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async i=>{try{let t=e.startSpinner("Fetching CVMs"),r=await ve();if(t.stop(!0),!r||r.length===0){e.info("No CVMs found");return}if(i.json){console.log(JSON.stringify(r,null,2));return}for(let o of r)e.keyValueTable({Name:o.name,"App ID":`app_${o.hosted.app_id}`,Status:o.status==="running"?de.green(o.status):o.status==="stopped"?de.red(o.status):de.yellow(o.status),"Node Info URL":o.hosted.app_url,"App URL":`${h}/dashboard/cvms/app_${o.hosted.app_id}`}),e.break();e.success(`Found ${r.length} CVMs`),e.break(),e.info(`Go to ${h}/dashboard/ to view your CVMs`)}catch(t){e.error(`Failed to list CVMs: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Kt}from"commander";import ue from"chalk";async function w(i){if(!i){let t=await Q();return t||void 0}return await W(i)}var Ze=new Kt().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(i,t)=>{try{let r=await w(i),o=e.startSpinner(`Fetching CVM with App ID app_${r}`),n=await V(r);if(o.stop(!0),e.break(),n||(e.error(`CVM with App ID app_${r} not found`),process.exit(1)),t.json){console.log(JSON.stringify(n,null,2));return}e.keyValueTable({Name:n.name,"App ID":`app_${n.app_id}`,Status:n.status==="running"?ue.green(n.status):n.status==="stopped"?ue.red(n.status):ue.yellow(n.status),vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"App URL":`${h}/dashboard/cvms/app_${n.app_id}`})}catch(r){e.error(`Failed to get CVM details: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Bt}from"commander";var Xe=new Bt().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 i=>{try{let t=await w(i),r=e.startSpinner(`Starting CVM with App ID app_${t}`),o=await Ce(t);r.stop(!0),e.break();let n={"CVM ID":o.id,Name:o.name,Status:o.status,"App ID":`app_${o.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being started. You can check the dashboard for more details:
|
53
|
-
${h}/dashboard/cvms/app_${
|
54
|
-
${h}/dashboard/cvms/app_${
|
55
|
-
${h}/dashboard/cvms/app_${
|
56
|
-
`)){if(!n.trim()||n.trim().startsWith("#"))continue;let m=-1,a=!1,c="";for(let
|
57
|
-
`))):s=s.trim(),
|
58
|
-
phala cvms get app_${S.app_id}`)}catch(t){e.error(`Failed to create CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as
|
59
|
-
${h}/dashboard/cvms/app_${r}`)}catch(r){e.error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as
|
60
|
-
`;if(e.keyValueTable({vCPUs:
|
61
|
-
${h}/dashboard/cvms/app_${r}`)}catch(r){e.error(`Failed to resize CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});var
|
48
|
+
`)}return m.background&&(l.unref(),e.success("Simulator is running in the background")),await de(),l}catch(t){throw e.error("Error running simulator:",t),new Error(`Failed to run simulator: ${t}`)}}async function te(){try{let o=z(),t=C.platforms[o];if(o==="darwin"||o==="linux"){let r="/tmp/tappd.sock";return b.existsSync(r)?new Promise(i=>{let n=le.createConnection({path:r}).on("connect",()=>{n.end(),i(!0)}).on("error",()=>{i(!1)});setTimeout(()=>{n.end(),i(!1)},1e3)}):!1}if(o==="win32"){let r="127.0.0.1";return new Promise(n=>{let m=le.createConnection({host:r,port:8090}).on("connect",()=>{m.end(),n(!0)}).on("error",()=>{n(!1)});setTimeout(()=>{m.end(),n(!1)},1e3)})}return!1}catch(o){return e.error("Error checking if simulator is running:",o),!1}}async function Ue(){try{let o=z();if(!await te())return e.info("Simulator is not running"),!0;e.info("Stopping simulator..."),o==="win32"?L(`for /f "tokens=5" %a in ('netstat -ano ^| findstr :8080') do taskkill /F /PID %a`,{stdio:"inherit"}):L("pkill -f tappd-simulator",{stdio:"inherit"});let t=!await te();return t?e.success("Simulator stopped successfully"):e.error("Failed to stop simulator"),await T(),t}catch(o){return e.error("Error stopping simulator:",o),!1}}function Tt(){return z()==="win32"?"http://127.0.0.1:8090":"unix:///tmp/tappd.sock"}async function de(o){try{let t=Tt(),r=o||t;return await L(`export DSTACK_SIMULATOR_ENDPOINT=${r}`),e.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${r} for current process`),o}catch(t){throw e.error("Error setting simulator endpoint environment variable:",t),new Error(`Failed to set simulator endpoint: ${t}`)}}async function T(){return await L("unset DSTACK_SIMULATOR_ENDPOINT"),e.debug("Deleted DSTACK_SIMULATOR_ENDPOINT from current process"),!0}var j=Lt(Nt),ze=".phala-cloud/logs",Ut=".phala-cloud/compose",Ke=10,v=class{username;image;registry;constructor(t,r,i){this.image=t,this.username=r||"",this.registry=i||""}ensureLogsDir(){let t=K.resolve(ze);E.existsSync(t)||E.mkdirSync(t,{recursive:!0})}getLogFilePath(t,r){let i=new Date().toISOString().replace(/[:.]/g,"-");return K.resolve(ze,`${r||this.image}-${t}-${i}.log`)}getSystemArchitecture(){let t=Oe.arch();switch(t){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return t}}spawnProcess(t,r,i,n){return new Promise((m,a)=>{let c=Rt(t,r);this.ensureLogsDir();let l=this.getLogFilePath(i,n),s=E.createWriteStream(l,{flags:"a"}),f=[],g=(p,u=!1)=>{let y=p.toString().split(`
|
49
|
+
`);s.write(p);for(let d of y)if(d.trim()){f.push(d),f.length>Ke&&f.shift(),console.clear(),console.log(`Latest ${Ke} lines (full log at ${l}):`),console.log("-".repeat(50));for(let I of f)u?console.error(I):console.log(I)}};c.stdout.on("data",p=>g(p)),c.stderr.on("data",p=>g(p,!0)),c.on("close",p=>{s.end(),p===0?(console.log(`
|
50
|
+
Operation completed. Full log available at: ${l}`),m()):a(new Error(`Process exited with code ${p}. Check log file: ${l}`))}),c.on("error",p=>{s.end(),a(p)})})}setCredentials(t,r){this.username=t,r&&(this.registry=r)}async buildImage(t,r){try{let i=this.getSystemArchitecture(),n=`${this.username}/${this.image}:${r}`,m=e.startSpinner(`Building Docker image ${this.username}/${this.image}:${r}`);P(t);let a=["build","-t",n,"-f",t];return i==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),a.push("--platform","linux/amd64")),a.push("."),await this.spawnProcess("docker",a,"build",this.image),m.stop(!0,`Docker image ${n} built successfully`),!0}catch(i){return e.error(`Failed to build Docker image: ${i instanceof Error?i.message:String(i)}`),!1}}async pushImage(t){try{let r=e.startSpinner(`Pushing Docker image ${t} to Docker Hub`);if(!await _())throw r.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let n=t;return console.log(`Pushing image ${n} to Docker Hub...`),await this.spawnProcess("docker",["push",n],"push",t.replace(/.*\/+([\w-]+):.*$/g,"$1")),r.stop(!0,`Docker image ${n} pushed successfully`),!0}catch(r){return e.error(`Failed to push Docker image: ${r instanceof Error?r.message:String(r)}`),!1}}async login(t,r,i){try{let n=e.startSpinner(`Logging in to Docker Hub as ${t}`);if(await this.checkLogin())return n.stop(!0,"Already logged in to Docker Hub"),this.setCredentials(t,i),!0;if(!r)throw n.stop(!1),new Error("Password is required for Docker login");try{await Mt("docker",["login",...i?[i]:[],"-u",t,"--password-stdin"],{input:r,timeout:1e4})}catch(a){throw a.timedOut?(n.stop(!1),new Error("Docker login timed out. Please check your credentials and try again.")):a}return n.stop(!0,"Logged in to Docker Hub successfully"),this.setCredentials(t,i),!0}catch(n){return e.error(`Failed to login to Docker Hub: ${n instanceof Error?n.message:String(n)}`),!1}}async checkLogin(){try{let t=Oe.homedir(),r=K.join(t,".docker","config.json");if(!E.existsSync(r))return!1;let i=JSON.parse(E.readFileSync(r,"utf-8"));return!!(i?.auths&&Object.keys(i.auths).length>0)}catch(t){return e.debug(`Docker login check failed: ${t instanceof Error?t.message:String(t)}`),!1}}async buildComposeFile(t,r,i){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let n=i==="eliza"?ye:ve,m=Ce.parse({template:n}),a=K.resolve(Ut);E.existsSync(a)||(e.info(`Creating directory: ${a}`),E.mkdirSync(a,{recursive:!0}));let c=[];r&&(c=E.readFileSync(r,"utf-8").split(`
|
51
|
+
`).filter(u=>u&&!u.startsWith("#")).map(u=>{let y=u.indexOf("#");return y>0&&(u=u.substring(0,y).trim()),u.trim()}).filter(u=>u.includes("=")).map(u=>{let[y,d]=u.split("=",2),I=y.trim();return(d?d.trim():"")===""?null:`${I}=${I}`}).filter(Boolean));let l=t,f=Vt.compile(m.template,{noEscape:!0})({imageName:l,envVars:c.map(p=>p.replace(/=.*/,`=\${${p.split("=")[0]}}`))}),g=K.join(a,`${t.replace(/.*\/+([\w-]+):.*$/g,"$1")}-tee-compose.yaml`);return E.writeFileSync(g,f),e.success(`Backup of docker compose file created at: ${g}`),g}async runComposeLocally(t,r){try{let i=e.startSpinner(`Running Docker Compose file at ${t}`);P(t);let n=["-f",t,"up","-d"];return r&&(P(r),n.splice(2,0,"--env-file",r)),await j(`docker compose ${n.join(" ")}`),i.stop(!0,"Docker Compose file running successfully"),!0}catch(i){return e.error(`Failed to run Docker Compose file: ${i instanceof Error?i.message:String(i)}`),!1}}async runSimulator(t,r){try{e.info(`Running TEE simulator with image ${t}`),e.info("Pulling latest simulator image..."),await j(`docker pull ${t}`),e.info("Starting simulator in background...");let{stdout:i}=await j(`docker run -d --name tee-simulator --rm -p ${r}:${r} ${t}`),n=i.trim();return e.success(`TEE simulator running successfully. Container ID: ${n}`),e.break(),e.break(),e.info("Useful commands:"),e.info(`- View logs: docker logs -f ${n}`),e.info(`- Stop simulator: docker stop ${n}`),de(`http://localhost:${r}`),!0}catch(i){return e.error(`Failed to run TEE simulator: ${i instanceof Error?i.message:String(i)}`),!1}}async stopSimulator(){try{let t=e.startSpinner("Stopping TEE simulator...");return await j("docker stop tee-simulator"),await T(),t.stop(!0,"TEE simulator stopped successfully"),!0}catch(t){return e.error(`Failed to stop TEE simulator: ${t instanceof Error?t.message:String(t)}`),!1}}static async listLocalImages(){try{let{stdout:t}=await j('docker images --format "{{.Repository}}:{{.Tag}}"'),i=(await _())?.username;return t.split(`
|
52
|
+
`).filter(m=>m&&!m.includes("<none>")).filter(m=>m.includes(`${i}/`)).map(m=>({imageName:m}))}catch(t){return e.error(`Failed to list local Docker images: ${t instanceof Error?t.message:String(t)}`),[]}}};import je from"prompts";var Be=new Ot().name("login").description("Login to Docker Hub").option("-u, --username <username>","Docker Hub username").option("-p, --password <password>","Docker Hub password").option("-r, --registry <registry>","Docker registry URL").action(async o=>{try{let t=o.username,r=o.password,i=o.registry;if(!t){e.info("First we need your Docker Hub username to check if you are already logged in.");let c=await je({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:l=>l.length>0?!0:"Username cannot be empty"});c.username||(e.error("Username is required"),process.exit(1)),t=c.username}let n=new v("",t,i);if(await n.login(t)){e.success(`${t} is logged in to Docker Hub`),await ne({username:t,registry:i||null});return}if(!r){let c=await je({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:l=>l.length>0?!0:"Password cannot be empty"});c.password||(e.error("Password is required"),process.exit(1)),r=c.password}await n.login(t,r,i)||(e.error("Failed to login to Docker Hub"),process.exit(1)),await ne({username:t,registry:i||null}),e.success("Logged in to Docker Hub successfully")}catch(t){e.error(`Failed to login to Docker Hub: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as zt}from"commander";import Ge from"node:path";import He from"inquirer";import Kt from"node:fs";var Ye=new zt().name("build").description("Build a Docker image").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").option("-f, --file <file>","Path to Dockerfile","Dockerfile").action(async o=>{try{let t=await _();if(t||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1)),!o.image){let a=await He.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:c=>c.trim()?!0:"Image name is required"}]);o.image=a.image}if(!o.tag){let a=await He.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:c=>c.trim()?!0:"Tag is required"}]);o.tag=a.tag}let r=Ge.resolve(process.cwd(),o.file);Kt.existsSync(r)||(e.info(`Default Dockerfile not found at ${r}`),o.file=await F("Enter the path to your Dockerfile:","Dockerfile","file"));let i=Ge.resolve(process.cwd(),o.file);await new v(o.image,t.username,t.registry).buildImage(i,o.tag)||(e.error("Failed to build Docker image"),process.exit(1)),e.success(`Docker image ${t.username}/${o.image}:${o.tag} built successfully`)}catch(t){e.error(`Failed to build Docker image: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as jt}from"commander";import Bt from"inquirer";var We=new jt().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Full image name (e.g. username/image:tag)").action(async o=>{try{let t=await _();t||(e.error('Docker information not found. Please login first with "phala docker login"'),process.exit(1));let r=o.image;if(!r){let m=await v.listLocalImages();if(m.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let a=Array.from(new Set(m.map(l=>l.imageName))),{selectedImage:c}=await Bt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:a}]);r=c}}await new v("",t.username,t.registry).pushImage(r)||(e.error("Failed to push Docker image"),process.exit(1)),e.success(`Docker image ${r} pushed successfully`)}catch(t){e.error(`Failed to push Docker image: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Gt}from"commander";import B from"inquirer";import G from"node:fs";import re from"node:path";var qe=new Gt().name("generate").description("Generate a Docker Compose file").option("-i, --image <imageName>","Docker image name to use in the compose file (e.g. phala/phala-cloud)").option("-e, --env-file <envFile>","Path to environment variables file").option("-o, --output <output>","Output path for generated docker-compose.yml").option("--template <template>","Template to use for the generated docker-compose.yml").action(async o=>{try{let t=await _();(!t||!t.username)&&(e.error("Docker Hub username not found. Please login first with `phala docker login`"),process.exit(1));let r=o.image;if(!r){let c=await v.listLocalImages();if(c.length===0&&(e.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!r){let l=Array.from(new Set(c.map(f=>f.imageName))),{selectedImage:s}=await B.prompt([{type:"list",name:"selectedImage",message:"Select an image to use in the compose file:",choices:l}]);r=s}}let i=o.envFile;if(i)try{P(i)}catch{e.error(`File not found: ${i}`),process.exit(1)}else{let c=re.join(process.cwd(),".env");if(G.existsSync(c)){let{useDefault:s}=await B.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);s&&(i=c)}if(!i){let{envPath:s}=await B.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:f=>{try{return P(f),!0}catch{return`File not found: ${f}`}}}]);i=s}}let n=o.output;if(!n&&(n=re.join(process.cwd(),"docker-compose.yml"),G.existsSync(n))){let{confirmOverwrite:c}=await B.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${n} already exists. Overwrite?`,default:!1}]);if(!c){let{customPath:l}=await B.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:re.join(process.cwd(),"docker-generated-compose.yml")}]);n=l}}let m=new v("",t.username,t.registry);i?e.info(`Generating Docker Compose file for ${r} using env file: ${i}`):e.info(`Generating Docker Compose file for ${r} without env file`);let a=await m.buildComposeFile(r,i,o.template);if(a!==n){let c=re.dirname(n);G.existsSync(c)||(e.info(`Creating directory: ${c}`),G.mkdirSync(c,{recursive:!0})),G.copyFileSync(a,n)}e.success(`Docker Compose file generated successfully: ${n}`)}catch(t){e.error(`Failed to generate Docker Compose file: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var Je=new Ht().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(Be).addCommand(Ye).addCommand(We).addCommand(qe);import{Command as qt}from"commander";import{Command as Yt}from"commander";var Qe=new Yt().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",he).option("-p, --port <port>","Simulator port (default: 8090)","8090").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async o=>{try{if(o.type==="docker")await new v("").runSimulator(o.image,o.port)||(e.error("Failed to start TEE simulator"),process.exit(1));else if(o.type==="native")if(Ne()||await Re(),await te()){e.success("TEE simulator is already running");return}else{let r=Le();e.success("TEE simulator started successfully")}else e.error("Invalid simulator type"),process.exit(1)}catch(t){e.error(`Failed to start TEE simulator: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Wt}from"commander";var Ze=new Wt().name("stop").description("Stop the TEE simulator").option("-t, --type <type>","Simulator type (docker, native)","docker").action(async o=>{try{o.type==="docker"?await new v("").stopSimulator()||(e.error("Failed to stop TEE simulator"),process.exit(1)):o.type==="native"?await Ue()||(e.error("Failed to stop TEE simulator"),process.exit(1)):(e.error("Invalid simulator type"),process.exit(1))}catch(t){e.error(`Failed to stop TEE simulator: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var Xe=new qt().name("simulator").description("TEE simulator commands").addCommand(Qe).addCommand(Ze);import{Command as gr}from"commander";import{Command as Jt}from"commander";import ue from"chalk";var et=new Jt().name("list").alias("ls").description("List all CVMs").option("-j, --json","Output in JSON format").action(async o=>{try{let t=e.startSpinner("Fetching CVMs"),r=await ke();if(t.stop(!0),!r||r.length===0){e.info("No CVMs found");return}if(o.json){console.log(JSON.stringify(r,null,2));return}for(let i of r)e.keyValueTable({Name:i.name,"App ID":`app_${i.hosted.app_id}`,"CVM ID":i.hosted.id.replace(/-/g,""),Region:i.node.region_identifier,Status:i.status==="running"?ue.green(i.status):i.status==="stopped"?ue.red(i.status):ue.yellow(i.status),"Node Info URL":i.hosted.app_url,"App URL":`${h}/dashboard/cvms/${i.hosted.id.replace(/-/g,"")}`}),e.break();e.success(`Found ${r.length} CVMs`),e.break(),e.info(`Go to ${h}/dashboard/ to view your CVMs`)}catch(t){e.error(`Failed to list CVMs: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Qt}from"commander";import fe from"chalk";async function w(o){if(!o){let t=await Z();return t||void 0}return await q(o)}var tt=new Qt().name("get").description("Get details of a CVM").argument("[app-id]","App ID of the CVM (optional)").option("-j, --json","Output in JSON format").action(async(o,t)=>{try{let r=await w(o),i=e.startSpinner(`Fetching CVM with App ID app_${r}`),n=await V(r);if(i.stop(!0),e.break(),n||(e.error(`CVM with App ID app_${r} not found`),process.exit(1)),t.json){console.log(JSON.stringify(n,null,2));return}e.keyValueTable({Name:n.name,"App ID":`app_${n.app_id}`,Status:n.status==="running"?fe.green(n.status):n.status==="stopped"?fe.red(n.status):fe.yellow(n.status),vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"App URL":`${h}/dashboard/cvms/app_${n.app_id}`})}catch(r){e.error(`Failed to get CVM details: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as Zt}from"commander";var rt=new Zt().name("start").description("Start a stopped CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let t=await w(o),r=e.startSpinner(`Starting CVM with App ID app_${t}`),i=await we(t);r.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being started. You can check the dashboard for more details:
|
53
|
+
${h}/dashboard/cvms/app_${i.app_id}`)}catch(t){e.error(`Failed to start CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as Xt}from"commander";var ot=new Xt().name("stop").description("Stop a running CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let t=await w(o),r=e.startSpinner(`Stopping CVM with App ID app_${t}`),i=await be(t);r.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being stopped. You can check the dashboard for more details:
|
54
|
+
${h}/dashboard/cvms/app_${i.app_id}`)}catch(t){e.error(`Failed to stop CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as er}from"commander";var it=new er().name("restart").description("Restart a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async o=>{try{let t=await w(o),r=e.startSpinner(`Restarting CVM with App ID app_${t}`),i=await Se(t);r.stop(!0),e.break();let n={"CVM ID":i.id,Name:i.name,Status:i.status,"App ID":`app_${i.app_id}`,"App URL":i.app_url?i.app_url:`${h}/dashboard/cvms/app_${i.app_id}`};e.keyValueTable(n,{borderStyle:"rounded"}),e.break(),e.success(`Your CVM is being restarted. You can check the dashboard for more details:
|
55
|
+
${h}/dashboard/cvms/app_${i.app_id}`)}catch(t){e.error(`Failed to restart CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as tr}from"commander";import oe from"chalk";var nt=new tr().name("attestation").description("Get attestation information for a CVM").argument("[app-id]","CVM app ID (will prompt for selection if not provided)").option("-j, --json","Output in JSON format").action(async(o,t)=>{try{let r;if(o)r=await q(o);else{e.info("No CVM specified, fetching available CVMs...");let n=await Z();if(!n)return;r=n}let i=e.startSpinner(`Fetching attestation information for CVM app_${r}...`);try{let n=await $e(r);if(i.stop(!0),!n||Object.keys(n).length===0){e.info("No attestation information found");return}if(t?.json){e.info(JSON.stringify(n,null,2));return}e.success("Attestation Summary:");let m={Status:n.is_online?oe.green("Online"):oe.red("Offline"),"Public Access":n.is_public?oe.green("Enabled"):oe.yellow("Disabled"),Error:n.error||"None",Certificates:`${n.app_certificates?.length||0} found`};if(e.keyValueTable(m,{borderStyle:"rounded"}),n.app_certificates&&n.app_certificates.length>0&&n.app_certificates.forEach((a,c)=>{e.break(),e.success(`Certificate #${c+1} (${a.position_in_chain===0?"End Entity":"CA"}):`);let l={Subject:`${a.subject.common_name||"Unknown"}${a.subject.organization?` (${a.subject.organization})`:""}`,Issuer:`${a.issuer.common_name||"Unknown"}${a.issuer.organization?` (${a.issuer.organization})`:""}`,"Serial Number":a.serial_number,Validity:`${new Date(a.not_before).toLocaleString()} to ${new Date(a.not_after).toLocaleString()}`,Fingerprint:a.fingerprint,"Signature Algorithm":a.signature_algorithm,"Is CA":a.is_ca?"Yes":"No","Position in Chain":a.position_in_chain};e.keyValueTable(l,{borderStyle:"rounded"})}),n.tcb_info){e.break(),e.success("Trusted Computing Base (TCB) Information:");let a={Mrtd:n.tcb_info.mrtd,"Rootfs Hash":n.tcb_info.rootfs_hash,Rtmr0:n.tcb_info.rtmr0,Rtmr1:n.tcb_info.rtmr1,Rtmr2:n.tcb_info.rtmr2,Rtmr3:n.tcb_info.rtmr3,"Event Log Entries":`${n.tcb_info.event_log.length} entries`};if(e.keyValueTable(a,{borderStyle:"rounded"}),n.tcb_info.event_log&&n.tcb_info.event_log.length>0){e.break(),e.success("Event Log (Showing entries to reproduce RTMR3):");let c=5,l=n.tcb_info.event_log.filter(s=>s.event!==null&&s.event!=="").map(s=>({Event:s.event,IMR:s.imr.toString(),"Event Type":s.event_type.toString(),Payload:s.event_payload}));e.table(l,[{key:"Event",header:"Event",minWidth:8},{key:"IMR",header:"IMR",minWidth:3},{key:"Event Type",header:"Type",minWidth:8},{key:"Payload",header:"Payload",minWidth:25}]),n.tcb_info.event_log.length>c&&e.info("To see all full attestation data, use --json"),e.break(),e.success("To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/")}}}catch(n){throw i.stop(!1),n}}catch(r){e.error(`Failed to get attestation information: ${r instanceof Error?r.message:String(r)}`)}});import{Command as rr}from"commander";import{encryptEnvVars as or}from"@phala/dstack-sdk/encrypt-env-vars";import st from"node:fs";import ir from"node:path";import mt from"inquirer";import*as at from"node:fs";var M=(o,t)=>{let r={};if(o){for(let i of o)if(i.includes("=")){let[n,...m]=i.split("="),a=m.join("=");n&&(r[n]=a)}}if(t){let i=at.readFileSync(t,"utf8");for(let n of i.split(`
|
56
|
+
`)){if(!n.trim()||n.trim().startsWith("#"))continue;let m=-1,a=!1,c="";for(let d=0;d<n.length;d++)if((n[d]==='"'||n[d]==="'"||n[d]==="`")&&(d===0||n[d-1]!=="\\"))a&&n[d]===c?(a=!1,c=""):a||(a=!0,c=n[d]);else if(n[d]==="="&&!a){m=d;break}else if(n[d]==="#"&&!a)break;if(m===-1){n.trim().startsWith("#");continue}let l=n.substring(0,m).trim(),s=n.substring(m+1),f=!1,g="",p=-1;for(let d=0;d<s.length;d++)if((s[d]==='"'||s[d]==="'"||s[d]==="`")&&(d===0||s[d-1]!=="\\"))f&&s[d]===g?(f=!1,g=""):f||(f=!0,g=s[d]);else if(s[d]==="#"&&!f&&d>0&&s[d-1]===" "){p=d-1;break}else if(s[d]==="#"&&!f&&d===0){p=d;break}p!==-1&&(s=s.substring(0,p)),s===void 0&&(s="");let u=s.charAt(0),y=s.charAt(s.length-1);u==='"'&&y==='"'||u==="'"&&y==="'"||u==="`"&&y==="`"?(s=s.substring(1,s.length-1),u==='"'&&(s=s.replace(/\\\\n/g,`
|
57
|
+
`))):s=s.trim(),l&&(r[l]=s)}}return Object.entries(r).map(([i,n])=>({key:i,value:n}))};var ct=new rr().name("create").description("Create a new CVM").option("-n, --name <name>","Name of the CVM").option("-c, --compose <compose>","Path to Docker Compose file").option("--vcpu <vcpu>",`Number of vCPUs, default is ${ae}`).option("--memory <memory>",`Memory in MB, default is ${se}`).option("--disk-size <diskSize>",`Disk size in GB, default is ${me}`).option("--teepod-id <teepodId>","TEEPod ID to use. If not provided, it will be selected from the list of available TEEPods.").option("--image <image>","Version of dstack image to use. If not provided, it will be selected from the list of available images for the selected TEEPod.").option("-e, --env-file <envFile>","Path to environment file").option("--skip-env","Skip environment variable prompt",!1).option("--debug","Enable debug mode",!1).action(async o=>{try{if(!o.name){let{name:k}=await mt.prompt([{type:"input",name:"name",message:"Enter a name for the CVM:",validate:$=>$.trim()?$.trim().length>20?"CVM name must be less than 20 characters":$.trim().length<3?"CVM name must be at least 3 characters":/^[a-zA-Z0-9_-]+$/.test($)?!0:"CVM name must contain only letters, numbers, underscores, and hyphens":"CVM name is required"}]);o.name=k}if(!o.compose){let $=ee(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");o.compose=await F("Enter the path to your Docker Compose file:",$,"file")}let t=ir.resolve(o.compose);st.existsSync(t)||(e.error(`Docker Compose file not found: ${t}`),process.exit(1));let r=st.readFileSync(t,"utf8");await T(),process.env.DSTACK_DOCKER_USERNAME&&process.env.DSTACK_DOCKER_PASSWORD?e.info("\u{1F510} Using private DockerHub registry credentials..."):process.env.DSTACK_AWS_ACCESS_KEY_ID&&process.env.DSTACK_AWS_SECRET_ACCESS_KEY&&process.env.DSTACK_AWS_REGION&&process.env.DSTACK_AWS_ECR_REGISTRY?e.info(`\u{1F510} Using private AWS ECR registry: ${process.env.DSTACK_AWS_ECR_REGISTRY}`):e.info("\u{1F510} Using public DockerHub registry...");let i=[];if(o.envFile)try{i=M([],o.envFile)}catch(k){e.error(`Failed to read environment file: ${k instanceof Error?k.message:String(k)}`),process.exit(1)}else if(!o.skipEnv){let{shouldSkip:k}=await mt.prompt([{type:"confirm",name:"shouldSkip",message:"Do you want to skip environment variable prompt?",default:!0}]);if(k)e.info("Skipping environment variable prompt");else{let $=await F("Enter the path to your environment file:",".env","file");i=M([],$)}}let n=Number(o.vcpu)||ae,m=Number(o.memory)||se,a=Number(o.diskSize)||me;(Number.isNaN(n)||n<=0)&&(e.error(`Invalid number of vCPUs: ${n}`),process.exit(1)),(Number.isNaN(m)||m<=0)&&(e.error(`Invalid memory: ${m}`),process.exit(1)),(Number.isNaN(a)||a<=0)&&(e.error(`Invalid disk size: ${a}`),process.exit(1));let c=e.startSpinner("Fetching available TEEPods"),l=await N();c.stop(!0),l.nodes.length===0&&(e.error("No TEEPods available. Please try again later."),process.exit(1));let s;o.teepodId?(s=l.nodes.find(k=>k.teepod_id===Number(o.teepodId)),s||(e.error("Failed to find selected TEEPod"),process.exit(1))):(s=l.nodes[0],s||(e.error("Failed to find default TEEPod"),process.exit(1)));let f;o.image?(f=s.images?.find(k=>k.name===o.image),f||(e.error(`Failed to find selected image: ${o.image}`),process.exit(1))):(f=s.images?.find(k=>k.name===O),f||(e.error(`Failed to find default image ${O}`),process.exit(1)));let g={teepod_id:s.teepod_id,name:o.name,image:f.name,vcpu:n,memory:m,disk_size:a,compose_manifest:{docker_compose_file:r,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:o.name,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},p=e.startSpinner("Getting public key from CVM"),u=await J(g);p.stop(!0),u||(e.error("Failed to get public key from CVM"),process.exit(1));let y=e.startSpinner("Encrypting environment variables"),d=await or(i,u.app_env_encrypt_pubkey);y.stop(!0),o.debug&&(e.debug("Public key:",u.app_env_encrypt_pubkey),e.debug("Encrypted environment variables:",d),e.debug("Environment variables:",JSON.stringify(i)));let I=e.startSpinner("Creating CVM"),S=await Q({...g,encrypted_env:d,app_env_encrypt_pubkey:u.app_env_encrypt_pubkey,app_id_salt:u.app_id_salt});I.stop(!0),S||(e.error("Failed to create CVM"),process.exit(1)),e.success("CVM created successfully"),e.break();let Et={"CVM ID":S.id,Name:S.name,Status:S.status,"App ID":`app_${S.app_id}`,"App URL":S.app_url?S.app_url:`${h}/dashboard/cvms/app_${S.app_id}`};e.keyValueTable(Et,{borderStyle:"rounded"}),e.info(""),e.success(`Your CVM is being created. You can check its status with:
|
58
|
+
phala cvms get app_${S.app_id}`)}catch(t){e.error(`Failed to create CVM: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as nr}from"commander";import ar from"inquirer";var pt=new nr().name("delete").description("Delete a CVM").argument("[app-id]","App ID of the CVM to delete (if not provided, a selection prompt will appear)").option("-f, --force","Skip confirmation prompt",!1).action(async(o,t)=>{try{let r=await w(o);if(!t.force){let{confirm:m}=await ar.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID app_${r}? This action cannot be undone.`,default:!1}]);if(!m){e.info("Deletion cancelled");return}}let i=e.startSpinner(`Deleting CVM app_${r}`),n=await Ee(r);i.stop(!0),n||(e.error(`Failed to delete CVM app_${r}`),process.exit(1)),e.success(`CVM app_${r} deleted successfully`)}catch(r){e.error(`Failed to delete CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as sr}from"commander";import mr from"node:fs";import{encryptEnvVars as cr}from"@phala/dstack-sdk/encrypt-env-vars";var lt=new sr().name("upgrade").description("Upgrade a CVM to a new version").argument("[app-id]","CVM app ID to upgrade (will prompt for selection if not provided)").option("-c, --compose <compose>","Path to new Docker Compose file").option("-e, --env-file <envFile>","Path to environment file").option("--debug","Enable debug mode",!1).action(async(o,t)=>{try{let r=await w(o),i=e.startSpinner(`Fetching current configuration for CVM app_${r}`),n=await V(r);if(i.stop(!0),n||(e.error(`CVM with App ID app_${r} not found`),process.exit(1)),!t.compose){let g=ee(["docker-compose.yml","docker-compose.yaml"],"Detected docker compose file: {path}");t.compose=await F("Enter the path to your Docker Compose file:",g,"file")}let m="";if(t.compose)try{m=mr.readFileSync(t.compose,"utf8")}catch(f){e.error(`Failed to read Docker Compose file: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}await T(),process.env.DSTACK_DOCKER_USERNAME&&process.env.DSTACK_DOCKER_PASSWORD?e.info("\u{1F510} Using private DockerHub registry credentials..."):process.env.DSTACK_AWS_ACCESS_KEY_ID&&process.env.DSTACK_AWS_SECRET_ACCESS_KEY&&process.env.DSTACK_AWS_REGION&&process.env.DSTACK_AWS_ECR_REGISTRY?e.info(`\u{1F510} Using private AWS ECR registry: ${process.env.DSTACK_AWS_ECR_REGISTRY}`):e.info("\u{1F510} Using public DockerHub registry...");let a="";if(t.envFile){let f=[];if(t.envFile)try{f=M([],t.envFile),a=await cr(f,n.encrypted_env_pubkey)}catch(g){e.error(`Failed to read environment file: ${g instanceof Error?g.message:String(g)}`),process.exit(1)}}let c={compose_manifest:{docker_compose_file:m,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${r}`},encrypted_env:a,allow_restart:!0},l=e.startSpinner(`Upgrading CVM app_${r}`),s=await _e(r,c);s||(l.stop(!1),e.error("Failed to upgrade CVM"),process.exit(1)),l.stop(!0),s.detail&&e.info(`Details: ${s.detail}`),e.break(),e.success(`Your CVM is being upgraded. You can check the dashboard for more details:
|
59
|
+
${h}/dashboard/cvms/app_${r}`)}catch(r){e.error(`Failed to upgrade CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as pr}from"commander";import H from"inquirer";import x from"chalk";var dt=new pr().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(o,t)=>{try{let r=await w(o),i=await V(r),n=t.vcpu,m=t.memory,a=t.diskSize,c=t.allowRestart;n||(n=(await H.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:p=>{let u=parseInt(p);return isNaN(u)||u<0?"Please enter a valid non-negative number":!0},default:i.vcpu,filter:p=>parseInt(p)}])).vcpu),m||(m=(await H.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:p=>{let u=parseInt(p);return isNaN(u)||u<0?"Please enter a valid non-negative number":!0},default:i.memory,filter:p=>parseInt(p)}])).memory),a||(a=(await H.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:p=>{let u=parseInt(p);return isNaN(u)||u<0?"Please enter a valid non-negative number":!0},default:i.disk_size,filter:p=>parseInt(p)}])).diskSize),c||(c=(await H.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let l=`Are you sure you want to resize CVM app_${r} with the following changes:
|
60
|
+
`;if(e.keyValueTable({vCPUs:i.vcpu!==n?`${x.red(i.vcpu)} -> ${x.green(n)}`:i.vcpu,Memory:i.memory!==m?`${x.red(i.memory)} MB -> ${x.green(m)} MB`:i.memory,"Disk Size":i.disk_size!==a?`${x.red(i.disk_size)} GB -> ${x.green(a)} GB`:i.disk_size,"Allow Restart":c?x.green("Yes"):x.red("No")}),!t.yes){let{confirm:g}=await H.prompt([{type:"confirm",name:"confirm",message:l,default:!1}]);if(!g){e.info("Resize operation cancelled");return}}let s=e.startSpinner(`Resizing CVM with App ID app_${r}`);await Ie(r,n,m,a,c?1:0),s.stop(!0),e.break(),e.success(`Your CVM is being resized. You can check the dashboard for more details:
|
61
|
+
${h}/dashboard/cvms/app_${r}`)}catch(r){e.error(`Failed to resize CVM: ${r instanceof Error?r.message:String(r)}`),process.exit(1)}});import{Command as lr}from"commander";var ut=new lr().name("list-nodes").description("List all available worker nodes.").action(async()=>{try{let{nodes:o,kms_list:t}=await N();if(o.length===0){e.info("No available nodes found.");return}e.info("Available Nodes:"),o.forEach(r=>{e.info("----------------------------------------"),e.info(` ID: ${r.teepod_id}`),e.info(` Name: ${r.name}`),e.info(` Region: ${r.region_identifier}`),e.info(` FMSPC: ${r.fmspc||"N/A"}`),e.info(` Device ID: ${r.device_id||"N/A"}`),e.info(` Support Onchain KMS: ${r.support_onchain_kms}`),e.info(" Images:"),r.images&&r.images.length>0?r.images.forEach(i=>{e.info(` - ${i.name}`),e.info(` Hash: ${i.os_image_hash||"N/A"}`)}):e.info(" N/A")}),t&&t.length>0&&(e.info(`
|
62
|
+
Available KMS Instances:`),t.forEach(r=>{e.info("----------------------------------------"),e.info(` ID: ${r.id}`),e.info(` URL: ${r.url}`),e.info(` Version: ${r.version}`),e.info(` Chain ID: ${r.chain_id}`),e.info(` Contract Address: ${r.kms_contract_address}`),e.info(` Gateway App ID: ${r.gateway_app_id}`)}))}catch(o){e.error(`Failed to list available nodes: ${o instanceof Error?o.message:String(o)}`)}});import{Command as dr}from"commander";import{encryptEnvVars as ur}from"@phala/dstack-sdk/encrypt-env-vars";import ft from"node:fs";import fr from"node:path";var gt=new dr().name("replicate").description("Create a replica of an existing CVM").argument("<cvm-id>","UUID of the CVM to replicate").option("--teepod-id <teepodId>","TEEPod ID to use for the replica").option("-e, --env-file <envFile>","Path to environment file").action(async(o,t)=>{try{let r;if(o=o.replace(/-/g,""),t.envFile){let a=fr.resolve(process.cwd(),t.envFile);if(!ft.existsSync(a))throw new Error(`Environment file not found: ${a}`);let l=ft.readFileSync(a,"utf-8").split(`
|
63
|
+
`).filter(g=>g.trim()!==""&&!g.trim().startsWith("#")).map(g=>{let[p,...u]=g.split("=");return{key:p.trim(),value:u.join("=").trim()}}),s=await De(o);e.info("Encrypting environment variables..."),r=await ur(l,s.env_pubkey)}let i={};t.teepodId&&(i.teepod_id=parseInt(t.teepodId,10)),r&&(i.encrypted_env=r);let n=await xe(o,i);e.success(`Successfully created replica of CVM UUID: ${o} with App ID: ${n.app_id}`);let m={"CVM UUID":n.vm_uuid.replace(/-/g,""),"App ID":n.app_id,Name:n.name,Status:n.status,TEEPod:`${n.teepod.name} (ID: ${n.teepod_id})`,vCPUs:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"App URL":n.app_url||`${process.env.CLOUD_URL||"https://cloud.phala.network"}/dashboard/cvms/${n.vm_uuid.replace(/-/g,"")}`};e.keyValueTable(m,{borderStyle:"rounded"}),e.success(`Your CVM replica is being created. You can check its status with:
|
64
|
+
phala cvms get ${n.app_id}`)}catch(r){e.error("Failed to create CVM replica:",r instanceof Error?r.message:r),process.exit(1)}});var ht=new gr().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(nt).addCommand(ct).addCommand(pt).addCommand(tt).addCommand(et).addCommand(rt).addCommand(ot).addCommand(dt).addCommand(it).addCommand(lt).addCommand(ut).addCommand(gt);import{Command as hr}from"commander";import{execSync as Y}from"node:child_process";import*as vt from"node:os";function yr(o){let t=vt.platform();try{switch(t){case"darwin":Y(`open "${o}"`);break;case"win32":Y(`start "" "${o}"`);break;case"linux":try{Y(`xdg-open "${o}"`)}catch{try{Y(`gnome-open "${o}"`)}catch{Y(`kde-open "${o}"`)}}break;default:throw new Error(`Unsupported platform: ${t}`)}e.success(`Opened URL in your default browser: ${o}`)}catch(r){e.error(`Failed to open URL: ${r instanceof Error?r.message:String(r)}`),e.info(`Please manually open this URL in your browser: ${o}`)}}function yt(o){return new Promise(t=>setTimeout(t,o))}var Ct=new hr().name("join").alias("free").description("Join Phala Cloud! Get an account and deploy a CVM for FREE").action(async()=>{try{let o="https://cloud.phala.network/register?invite=beta",t=e.startSpinner("Brewing a fresh cup of TEE \u{1F375}");await yt(2e3),t.stop(!0),e.break(),e.break(),console.log(X),e.info("TEE is served! Opening Phala Cloud registration page..."),await yt(1e3),e.break(),yr(o)}catch(o){e.error(`Error: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as kr}from"commander";var vr=`version: '3'
|
62
65
|
services:
|
63
66
|
jupyter:
|
64
67
|
image: quay.io/jupyter/base-notebook
|
@@ -70,13 +73,14 @@ services:
|
|
70
73
|
- GRANT_SUDO=yes
|
71
74
|
user: root
|
72
75
|
command: "start-notebook.sh --NotebookApp.token=\${TOKEN}"
|
73
|
-
`,
|
76
|
+
`,Cr=`version: '3'
|
74
77
|
services:
|
75
78
|
httpbin:
|
76
79
|
image: kennethreitz/httpbin:latest
|
77
80
|
ports:
|
78
81
|
- "80:80"
|
79
|
-
`,
|
80
|
-
phala cvms get app_${p.app_id}`)}catch(
|
81
|
-
|
82
|
+
`,kt={jupyter:{compose:vr,name:"Jupyter Notebook"},httpbin:{compose:Cr,name:"HTTPBin"}};import{encryptEnvVars as wr}from"@phala/dstack-sdk/encrypt-env-vars";import wt from"inquirer";import br from"node:crypto";var bt=new kr().name("demo").description("Demo commands to launch a demo on Phala Cloud").action(async()=>{try{await W()||(e.error("You need to be logged in to use the demo command"),e.info("Please login with: phala auth login"),process.exit(1));try{let y=e.startSpinner("Verifying your credentials"),d=await A();y.stop(!0),e.success(`Logged in as ${d.username}`)}catch{e.error("Authentication failed. Your API key may be invalid or expired."),e.info("Please set a new API key with: phala auth login"),process.exit(1)}let t=Object.values(kt);t.length===0&&(e.error("No template files found in the templates directory"),process.exit(1));let{selectedTemplate:r}=await wt.prompt([{type:"list",name:"selectedTemplate",message:"Select a template to deploy:",choices:t.map(y=>({name:y.name,value:y}))}]),i=r.compose;e.success(`Selected template: ${r.name}`);let n=br.randomBytes(16).toString("hex"),m=M([`TOKEN=${n}`],""),{cvmName:a}=await wt.prompt([{type:"input",name:"cvmName",message:"Enter a name for your CVM:",default:`${r.name.replace(" ","-")}`,validate:y=>y.trim()?!0:"CVM name is required"}]);e.info("Preparing to deploy your CVM...");let c={teepod_id:3,name:a,image:O,vcpu:2,memory:2048,disk_size:20,compose_manifest:{docker_compose_file:i,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:a,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},l=e.startSpinner("Preparing CVM configuration"),s=await J(c);l.stop(!0),s||(e.error("Failed to prepare CVM configuration"),process.exit(1));let f=await wr(m,s.app_env_encrypt_pubkey);e.debug("Public key:",s.app_env_encrypt_pubkey),e.debug("Encrypted environment variables:",f);let g=e.startSpinner("Creating your demo CVM"),p=await Q({...c,encrypted_env:f,app_env_encrypt_pubkey:s.app_env_encrypt_pubkey,app_id_salt:s.app_id_salt});g.stop(!0),p||(e.error("Failed to create demo CVM"),process.exit(1)),e.success("Demo CVM created successfully! \u{1F389}"),e.break();let u={"CVM ID":p.id,Name:p.name,Status:p.status,"App ID":`app_${p.app_id}`,"App URL":p.app_url?p.app_url:`${h}/dashboard/cvms/app_${p.app_id}`,Template:r.name,Resources:"2 vCPUs, 2GB RAM, 20GB Storage"};r.name.includes("Jupyter Notebook")&&(u["Jupyter Token"]=n,u["Access Instructions"]="Access your Jupyter notebook using the token above. Go to 'Network' tab to see the public URL."),e.keyValueTable(u,{borderStyle:"rounded"}),e.break(),e.success(`Your demo is being created. You can check its status with:
|
83
|
+
phala cvms get app_${p.app_id}`)}catch(o){e.error(`Failed to launch demo: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as St}from"commander";async function ge(){try{let{nodes:o,kms_list:t}=await N();if(o.length===0){e.info("No available nodes found.");return}e.info("Available Nodes:"),o.forEach(r=>{e.info("----------------------------------------"),e.info(` ID: ${r.teepod_id}`),e.info(` Name: ${r.name}`),e.info(` Region: ${r.region_identifier}`),e.info(` FMSPC: ${r.fmspc||"N/A"}`),e.info(` Device ID: ${r.device_id||"N/A"}`),e.info(` Support Onchain KMS: ${r.support_onchain_kms}`),e.info(" Images:"),r.images&&r.images.length>0?r.images.forEach(i=>{e.info(` - ${i.name}`),e.info(` Hash: ${i.os_image_hash||"N/A"}`)}):e.info(" N/A")}),t&&t.length>0&&(e.info(`
|
84
|
+
Available KMS Instances:`),t.forEach(r=>{e.info("----------------------------------------"),e.info(` ID: ${r.id}`),e.info(` URL: ${r.url}`),e.info(` Version: ${r.version}`),e.info(` Chain ID: ${r.chain_id}`),e.info(` Contract Address: ${r.kms_contract_address}`),e.info(` Gateway App ID: ${r.gateway_app_id}`)}))}catch(o){throw e.error(`Failed to list available nodes: ${o instanceof Error?o.message:String(o)}`),o}}var _t=new St().name("nodes").description("List and manage TEE nodes").action(ge).addCommand(new St("list").description("List all available worker nodes").alias("ls").action(ge));process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function _r(){new Sr().name("phala").alias("pha").description(`${X}
|
85
|
+
Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("v1.0.15").addCommand(Ve).addCommand(ht).addCommand(Je).addCommand(Xe).addCommand(bt).addCommand(Ct).addCommand(_t).parse(process.argv)}_r().catch(o=>{e.error("An error occurred:",o),process.exit(1)});
|
82
86
|
//# sourceMappingURL=index.js.map
|