phala 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/banner.ts","../src/commands/auth/index.ts","../src/commands/auth/login.ts","../src/utils/credentials.ts","../src/utils/logger.ts","../src/api/client.ts","../src/utils/constants.ts","../src/api/types.ts","../src/utils/types.ts","../src/api/auth.ts","../src/commands/auth/logout.ts","../src/commands/auth/status.ts","../src/commands/docker/index.ts","../src/commands/docker/login.ts","../src/utils/docker.ts","../src/utils/prompts.ts","../src/utils/simulator.ts","../src/commands/docker/build.ts","../src/commands/docker/push.ts","../src/commands/docker/generate.ts","../src/commands/simulator/index.ts","../src/commands/simulator/start.ts","../src/commands/simulator/stop.ts","../src/commands/cvms/index.ts","../src/commands/cvms/list.ts","../src/api/cvms.ts","../src/commands/cvms/get.ts","../src/utils/cvms.ts","../src/commands/cvms/start.ts","../src/commands/cvms/stop.ts","../src/commands/cvms/restart.ts","../src/commands/cvms/attestation.ts","../src/commands/cvms/create.ts","../src/api/teepods.ts","../src/utils/secrets.ts","../src/commands/cvms/delete.ts","../src/commands/cvms/upgrade.ts","../src/commands/cvms/resize.ts","../src/commands/join.ts","../src/commands/demo/index.ts","../src/utils/demo.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { Command } from \"commander\"\nimport { logo } from \"./utils/banner\"\nimport { authCommands } from \"./commands/auth\"\nimport { dockerCommands } from \"./commands/docker\"\nimport { simulatorCommands } from \"./commands/simulator\"\nimport { logger } from \"./utils/logger\"\nimport { cvmsCommand } from './commands/cvms'\nimport { joinCommand } from \"./commands/join\"\nimport { demoCommands } from \"./commands/demo\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = new Command()\n\t\t\t.name(\"phala\")\n\t\t\t.alias(\"pha\")\n\t\t\t.description(\n\t\t\t\t`${logo}\\nPhala Cloud CLI - Manage your Phala Cloud Deployments`,\n\t\t\t)\n\t\t\t.version(\"v1.0.4\")\n\t\t\t.addCommand(authCommands)\n\t\t\t.addCommand(cvmsCommand)\n\t\t\t.addCommand(dockerCommands)\n\t\t\t.addCommand(simulatorCommands)\n\t\t\t.addCommand(demoCommands)\n\t\t\t.addCommand(joinCommand);\n\n program.parse(process.argv)\n}\n\nmain().catch((error) => {\n logger.error(\"An error occurred:\", error)\n process.exit(1)\n})","import chalk from 'chalk';\nconst logoColor = chalk.hex('#cdfa50');\nexport const logo = logoColor(`\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣤⣤⣀⡀⠀⢀⣀⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠛⠉⠁⠀⠈⠉⠛⠿⠛⠉⠉⠉⠉⠙⠷⣄⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠞⠛⠉⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⢶⣄⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣦⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣿⡿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠃⠀⢀⣾⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠋⠁⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡤⠤⠤⠴⠒⠒⠒⠒⠒⢿⡿⠓⠒⠒⠢⠤⠤⠤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣯⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⣀⣨⣿⣦⣤⣀⡀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⡏⠉⠛⣿⣆⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⣀⣀⣀⣀⡸⠿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣸⡿⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⠀⢸⣿⣿⣿⣿⡇⠀⣿⣿⣿⣿⣿⣿⠃⢀⣠⣴⡿⠃⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⠿⢇⣀⣀⣀⣀⣸⣿⣿⣿⣿⣿⡿⠿⠿⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠈⠻⢿⣿⣿⣿⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠠⣄⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⠿⣿⣿⣿⣿⣿⠿⠟⠋⠁⠀⠀⠀⠀⠀⠀⣀⣾⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⢶⣦⣤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣤⣴⣶⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠻⠿⠿⠿⠿⢿⣿⣿⣿⠿⠿⠿⠿⠟⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n`);\n\nexport const smallLogo = logoColor(`\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣤⣤⣀⡀⠀⢀⣀⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠛⠉⠁⠀⠈⠉⠛⠿⠛⠉⠉⠉⠉⠙⠷⣄⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠞⠛⠉⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⢶⣄⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣦⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣿⡿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠃⠀⢀⣾⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠋⠁⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡤⠤⠤⠴⠒⠒⠒⠒⠒⢿⡿⠓⠒⠒⠢⠤⠤⠤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣯⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⣀⣨⣿⣦⣤⣀⡀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⡏⠉⠛⣿⣆⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⣀⣀⣀⣀⡸⠿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣸⡿⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⠀⢸⣿⣿⣿⣿⡇⠀⣿⣿⣿⣿⣿⣿⠃⢀⣠⣴⡿⠃⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⠿⢇⣀⣀⣀⣀⣸⣿⣿⣿⣿⣿⡿⠿⠿⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠈⠻⢿⣿⣿⣿⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠠⣄⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⠿⣿⣿⣿⣿⣿⠿⠟⠋⠁⠀⠀⠀⠀⠀⠀⣀⣾⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⢶⣦⣤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣤⣴⣶⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠻⠿⠿⠿⠿⢿⣿⣿⣿⠿⠿⠿⠿⠟⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n`);\n\nexport const minimalLogo = chalk.cyan('PHALA TEE CLOUD CLI');","import { Command } from 'commander';\nimport { loginCommand } from './login';\nimport { logoutCommand } from './logout';\nimport { statusCommand } from './status';\n\nexport const authCommands = new Command()\n .name('auth')\n .description('Authenticate with Phala Cloud')\n .addCommand(loginCommand)\n .addCommand(logoutCommand)\n .addCommand(statusCommand);\n","import { Command } from 'commander';\nimport { removeApiKey, saveApiKey } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport prompts from 'prompts';\nimport { getUserInfo } from '@/src/api/auth';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const loginCommand = new Command()\n .name('login')\n .description('Set the API key for authentication')\n .argument('[api-key]', 'Phala Cloud API key to set')\n .action(async (apiKey?: string) => {\n try {\n let checkUserInfo;\n // If no API key is provided, prompt for it\n if (!apiKey) {\n const response = await prompts({\n type: 'password',\n name: 'apiKey',\n message: 'Enter your API key:',\n validate: async (value) => {\n if (value.length === 0) {\n return 'API key cannot be empty';\n }\n try {\n await saveApiKey(value);\n checkUserInfo = await getUserInfo();\n if (!checkUserInfo.username) {\n await removeApiKey();\n return 'Invalid API key';\n }\n } catch (error) {\n return 'Invalid API key';\n }\n return true;\n }\n });\n \n apiKey = response.apiKey;\n } else {\n await saveApiKey(apiKey);\n // Validate the API key\n checkUserInfo = await getUserInfo();\n if (!checkUserInfo.username) {\n await removeApiKey();\n return 'Invalid API key';\n }\n }\n \n logger.success(`Welcome ${checkUserInfo.username}! API key validated and saved successfully`);\n logger.break();\n logger.info(`Open in Web UI at ${CLOUD_URL}/dashboard/`);\n } catch (error) {\n logger.error(`Failed to set API key: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport crypto from 'node:crypto';\nimport { logger } from './logger';\n\n// Define the directory and file for storing credentials\nconst PHALA_CLOUD_DIR = path.join(os.homedir(), '.phala-cloud');\nconst API_KEY_FILE = path.join(PHALA_CLOUD_DIR, 'api-key');\nconst DOCKER_CREDENTIALS_FILE = path.join(PHALA_CLOUD_DIR, 'docker-credentials.json');\n\n// Ensure the .phala-cloud directory exists\nfunction ensureDirectoryExists(): void {\n if (!fs.existsSync(PHALA_CLOUD_DIR)) {\n try {\n fs.mkdirSync(PHALA_CLOUD_DIR, { recursive: true });\n } catch (error) {\n logger.error(`Failed to create directory ${PHALA_CLOUD_DIR}:`, error);\n throw error;\n }\n }\n}\n\n// Generate a machine-specific encryption key\nfunction getMachineKey(): Buffer {\n // Create a deterministic but machine-specific key\n const machineParts = [\n os.hostname(),\n os.platform(),\n os.arch(),\n os.cpus()[0]?.model || '',\n os.userInfo().username\n ];\n \n // Create a hash of the machine parts\n const hash = crypto.createHash('sha256');\n hash.update(machineParts.join('|'));\n return hash.digest();\n}\n\n// Encrypt data\nfunction encrypt(text: string): string {\n try {\n const key = getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key.slice(0, 32), iv);\n \n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n // Return IV + encrypted data\n return iv.toString('hex') + ':' + encrypted;\n } catch (error) {\n logger.error('Encryption failed:', error);\n throw new Error('Failed to encrypt data');\n }\n}\n\n// Decrypt data\nfunction decrypt(encryptedText: string): string {\n try {\n const key = getMachineKey();\n const parts = encryptedText.split(':');\n \n if (parts.length !== 2) {\n throw new Error('Invalid encrypted format');\n }\n \n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n \n const decipher = crypto.createDecipheriv('aes-256-cbc', key.slice(0, 32), iv);\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n } catch (error) {\n logger.error('Decryption failed:', error);\n throw new Error('Failed to decrypt data');\n }\n}\n\n// API Key Management\nexport async function saveApiKey(apiKey: string): Promise<void> {\n ensureDirectoryExists();\n try {\n // Encrypt the API key before saving\n const encryptedApiKey = encrypt(apiKey);\n fs.writeFileSync(API_KEY_FILE, encryptedApiKey, { mode: 0o600 }); // Restrict permissions to user only\n } catch (error) {\n logger.error('Failed to save API key:', error);\n throw error;\n }\n}\n\nexport async function getApiKey(): Promise<string | null> {\n try {\n if (fs.existsSync(API_KEY_FILE)) {\n const encryptedApiKey = fs.readFileSync(API_KEY_FILE, 'utf8').trim();\n // Decrypt the API key\n return decrypt(encryptedApiKey);\n }\n return null;\n } catch (error) {\n logger.error('Failed to read API key:', error);\n return null;\n }\n}\n\nexport async function removeApiKey(): Promise<void> {\n try {\n if (fs.existsSync(API_KEY_FILE)) {\n fs.unlinkSync(API_KEY_FILE);\n logger.success('API key removed successfully.');\n } else {\n logger.warn('No API key found to remove.');\n }\n } catch (error) {\n logger.error('Failed to remove API key:', error);\n throw error;\n }\n}\n\n// Docker Credentials Management\ninterface DockerCredentials {\n username: string;\n registry?: string;\n}\n\nexport async function saveDockerCredentials(credentials: DockerCredentials): Promise<void> {\n ensureDirectoryExists();\n try {\n \n fs.writeFileSync(\n DOCKER_CREDENTIALS_FILE, \n JSON.stringify(credentials, null, 2), \n { mode: 0o600 } // Restrict permissions to user only\n );\n logger.success('Docker information saved successfully.');\n } catch (error) {\n logger.error('Failed to save Docker information:', error);\n throw error;\n }\n}\n\nexport async function getDockerCredentials(): Promise<DockerCredentials | null> {\n try {\n if (fs.existsSync(DOCKER_CREDENTIALS_FILE)) {\n const data = fs.readFileSync(DOCKER_CREDENTIALS_FILE, 'utf8');\n const credentials = JSON.parse(data) as DockerCredentials;\n \n return credentials;\n }\n return null;\n } catch (error) {\n logger.error('Failed to read Docker credentials:', error);\n return null;\n }\n}\n\nexport async function removeDockerCredentials(): Promise<void> {\n try {\n if (fs.existsSync(DOCKER_CREDENTIALS_FILE)) {\n fs.unlinkSync(DOCKER_CREDENTIALS_FILE);\n logger.success('Docker credentials removed successfully.');\n } else {\n logger.warn('No Docker credentials found to remove.');\n }\n } catch (error) {\n logger.error('Failed to remove Docker credentials:', error);\n throw error;\n }\n} ","import chalk from \"chalk\"\n\n/**\n * Strips ANSI color escape sequences from a string to get its visible length\n * @param str String that may contain ANSI color codes\n * @returns String with all ANSI color codes removed\n */\nfunction stripAnsi(str: string): string {\n // ANSI escape sequence regex pattern\n const pattern = [\n '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)',\n '(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TZcf-ntqry=><~]))'\n ].join('|');\n return str.replace(new RegExp(pattern, 'g'), '');\n}\n\n/**\n * Gets the visible length of a string, ignoring ANSI color codes\n * @param str String that may contain ANSI color codes\n * @returns Visible length of the string\n */\nfunction getVisibleLength(str: string): number {\n return stripAnsi(str).length;\n}\n\n/**\n * Wraps text to fit within a specified width\n * @param text Text to wrap\n * @param maxWidth Maximum width for the text\n * @returns Array of lines of text\n */\nfunction wrapText(text: string, maxWidth: number): string[] {\n if (!text) return [''];\n \n // Handle case where a single word is longer than maxWidth\n if (getVisibleLength(text) <= maxWidth) return [text];\n \n const lines: string[] = [];\n let currentLine = '';\n let currentLineVisibleLength = 0;\n \n // Split by any whitespace and preserve URLs\n const words = text.split(/(\\s+)/).filter(word => word.trim().length > 0);\n \n for (const word of words) {\n const wordVisibleLength = getVisibleLength(word);\n \n // If the word itself is longer than maxWidth, split it\n if (wordVisibleLength > maxWidth) {\n if (currentLine) {\n lines.push(currentLine);\n currentLine = '';\n currentLineVisibleLength = 0;\n }\n \n // This is a simplification as it's complex to split words with color codes\n // For long colored words, we'll just add them as-is\n lines.push(word);\n continue;\n }\n \n // If adding the word would exceed maxWidth\n if (currentLineVisibleLength + wordVisibleLength + (currentLineVisibleLength > 0 ? 1 : 0) > maxWidth) {\n lines.push(currentLine);\n currentLine = word;\n currentLineVisibleLength = wordVisibleLength;\n } else {\n // Add word to current line\n if (currentLine) {\n currentLine = `${currentLine} ${word}`;\n currentLineVisibleLength += wordVisibleLength + 1; // +1 for space\n } else {\n currentLine = word;\n currentLineVisibleLength = wordVisibleLength;\n }\n }\n }\n \n if (currentLine) {\n lines.push(currentLine);\n }\n \n return lines;\n}\n\nexport const logger = {\n error: (message: string, ...args: any[]) => {\n console.error(chalk.red('✗'), chalk.red(message), ...args)\n },\n warn: (message: string, ...args: any[]) => {\n console.log(chalk.yellow('⚠'), chalk.yellow(message), ...args)\n },\n info: (message: string, ...args: any[]) => {\n console.log(chalk.blue('ℹ'), chalk.blue(message), ...args)\n },\n success: (message: string, ...args: any[]) => {\n console.log(chalk.green('✓'), chalk.green(message), ...args)\n },\n debug: (message: string, ...args: any[]) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray('🔍'), chalk.gray(message), ...args)\n }\n },\n table: <T>(\n data: T[], \n columns?: Array<string> | Array<{ key: keyof T | string, header?: string }> | Array<any>\n ) => {\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n \n // Support for old API with just column names\n if (columns) {\n if (typeof columns[0] === 'string') {\n // Convert simple string array to column config\n const columnConfig = (columns as string[]).map(col => ({\n key: col,\n header: col.charAt(0).toUpperCase() + col.slice(1) // Capitalize\n }));\n \n // Filter data to only include specified columns\n formatTable(data, { \n columns: columnConfig,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n } else {\n // Using the new column config format\n formatTable(data, { \n columns: columns as Array<{ key: keyof T | string, header?: string }>,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n } else {\n // No columns specified, show all\n formatTable(data, {\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n },\n /**\n * Displays an object's properties in a key-value table format (vertical table)\n * @param data Object to display\n * @param options Table display options\n */\n keyValueTable: <T extends object>(\n data: T,\n options?: {\n include?: string[]; // Optional list of keys to include\n exclude?: string[]; // Optional list of keys to exclude\n keyFormatter?: (key: string) => string; // Optional formatter for keys\n valueFormatter?: (value: any, key: string) => string; // Optional formatter for values\n formatKeys?: boolean; // Whether to format keys (default: true)\n keyHeader?: string; // Optional header for the key column\n valueHeader?: string; // Optional header for the value column\n keyWidth?: number; // Optional fixed width for the key column\n valueWidth?: number; // Optional fixed width for the value column\n borderStyle?: 'single' | 'double' | 'rounded'; // Border style\n enableTextWrapping?: boolean; // Whether to wrap text\n maxDepth?: number; // Maximum depth for nested objects (default: 2)\n }\n ) => {\n // Default options\n const defaultOptions = {\n borderStyle: 'rounded' as const,\n enableTextWrapping: true,\n maxDepth: 2,\n formatKeys: true,\n // Improved key formatter with different formatting options\n keyFormatter: (key: string) => {\n // Common acronyms that should remain uppercase\n const commonAcronyms = [\n 'URL', 'ID', 'API', 'UI', 'URI', 'CPU', 'GPU', 'RAM', 'JSON', 'XML', 'HTML', \n 'HTTP', 'HTTPS', 'SSH', 'FTP', 'IP', 'TCP', 'UDP', 'DNS', 'SSL', 'TLS', 'SQL', \n 'VCPU', 'CVM', 'TEE', 'IO'\n ];\n \n // Phala-specific terms with custom capitalization\n const customTerms = {\n 'teepod': 'TEEPod',\n 'dstack': 'Dstack'\n };\n \n // Handle different cases\n let formatted;\n \n if (key.includes('_')) {\n // Handle snake_case: convert app_url to App Url\n formatted = key.split('_')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else if (key.includes('-')) {\n // Handle kebab-case: convert app-url to App Url\n formatted = key.split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else {\n // Handle camelCase: convert appUrl to App Url\n formatted = key.charAt(0).toUpperCase() + \n key.slice(1).replace(/([a-z])([A-Z])/g, '$1 $2');\n }\n \n // Replace common acronyms in the formatted text, preserving case\n for (const acronym of commonAcronyms) {\n // Only uppercase the whole acronym if it appears as a whole word\n const regex = new RegExp(`\\\\b${acronym.toLowerCase()}\\\\b`, 'gi');\n formatted = formatted.replace(regex, acronym);\n }\n \n // Apply custom term formatting\n for (const [term, replacement] of Object.entries(customTerms)) {\n const regex = new RegExp(`\\\\b${term}\\\\b`, 'gi');\n formatted = formatted.replace(regex, replacement);\n }\n \n return formatted;\n },\n valueFormatter: (value: any) => String(value ?? '')\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n const { include, exclude, keyFormatter, valueFormatter, formatKeys, keyWidth, valueWidth, borderStyle, enableTextWrapping, maxDepth } = mergedOptions;\n\n // Extract keys based on include/exclude\n let keys = Object.keys(data);\n if (include) {\n keys = keys.filter(key => include.includes(key));\n }\n if (exclude) {\n keys = keys.filter(key => !exclude.includes(key));\n }\n\n // If no keys to display, show message and return\n if (keys.length === 0) {\n console.log(chalk.yellow('No properties to display'));\n return;\n }\n\n // Prepare the data array for the table formatter\n const tableData = keys.map(key => {\n const value = data[key as keyof T];\n \n // Format the value based on its type\n let formattedValue: string;\n if (value === null || value === undefined) {\n formattedValue = '';\n } else if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle nested objects (but limit depth)\n formattedValue = formatNestedObject(value, 0, maxDepth);\n } else if (Array.isArray(value)) {\n // Handle arrays\n if (value.length === 0) {\n formattedValue = '[]';\n } else if (typeof value[0] === 'object') {\n // Array of objects\n formattedValue = `[${value.length} items]`;\n } else {\n // Array of primitives\n formattedValue = `[${value.join(', ')}]`;\n }\n } else {\n // Handle primitives\n formattedValue = String(value);\n }\n \n // Apply custom value formatter if provided\n if (valueFormatter) {\n formattedValue = valueFormatter(value, key);\n }\n \n return {\n key: formatKeys && keyFormatter ? chalk.cyan.bold(keyFormatter(key)) : chalk.cyan.bold(key),\n value: formattedValue\n };\n });\n\n // Calculate column widths based on content\n const terminalWidth = getTerminalWidth();\n let finalKeyWidth = keyWidth;\n let finalValueWidth = valueWidth;\n \n // Calculate key column width based on content if not specified\n if (!finalKeyWidth) {\n finalKeyWidth = Math.max(\n ...tableData.map(item => getVisibleLength(item.key)),\n 10 // Minimum key width\n );\n // Limit to 1/3 of terminal width\n finalKeyWidth = Math.min(finalKeyWidth, Math.floor(terminalWidth / 3));\n }\n \n // Calculate value column width based on content if not specified\n if (!finalValueWidth) {\n // Calculate based on actual content lengths\n finalValueWidth = Math.max(\n ...tableData.map(item => getVisibleLength(item.value)),\n 10 // Minimum value width\n );\n \n // Add some padding for readability (3 chars)\n finalValueWidth += 3;\n \n // Ensure we don't exceed terminal width\n const borderChars = 7; // Typical border chars count\n const maxValueWidth = terminalWidth - finalKeyWidth - borderChars;\n finalValueWidth = Math.min(finalValueWidth, maxValueWidth);\n }\n\n // Configure border characters based on style\n const border = getBorderChars(borderStyle);\n\n // Header row\n const topBorder = `${border.topLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.topT}${border.horizontal.repeat(finalValueWidth + 2)}${border.topRight}`;\n const headerSeparator = `${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`;\n \n console.log(topBorder);\n console.log(headerSeparator);\n \n // Data rows\n tableData.forEach((row, index) => {\n const keyLines = enableTextWrapping ? wrapText(row.key, finalKeyWidth) : [row.key];\n const valueLines = enableTextWrapping ? wrapText(row.value, finalValueWidth) : [row.value];\n \n const maxLines = Math.max(keyLines.length, valueLines.length);\n \n for (let i = 0; i < maxLines; i++) {\n const keyLine = keyLines[i] || '';\n const valueLine = valueLines[i] || '';\n \n // Pad with spaces to align columns, accounting for invisible ANSI characters\n const keyContent = keyLine + ' '.repeat(Math.max(0, finalKeyWidth - getVisibleLength(keyLine)));\n const valueContent = valueLine + ' '.repeat(Math.max(0, finalValueWidth - getVisibleLength(valueLine)));\n \n console.log(`${border.vertical} ${keyContent} ${border.vertical} ${valueContent} ${border.vertical}`);\n }\n \n // Add a separator between rows, but not after the last row\n if (index < tableData.length - 1) {\n console.log(`${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`);\n }\n });\n \n // Bottom border\n const bottomBorder = `${border.bottomLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.bottomT}${border.horizontal.repeat(finalValueWidth + 2)}${border.bottomRight}`;\n console.log(bottomBorder);\n },\n startSpinner: (message: string) => {\n process.stdout.write(`${chalk.blue('⟳')} ${message}... `)\n return {\n stop: (success = true, result?: string) => {\n const icon = success ? chalk.green('✓') : chalk.red('✗')\n const resultText = result ? `: ${result}` : ''\n console.log(`${icon}${resultText}`)\n }\n }\n },\n break() {\n console.log(\"\")\n },\n}\n\n/**\n * Formats a nested object for display in the keyValueTable\n */\nfunction formatNestedObject(obj: any, currentDepth: number, maxDepth: number): string {\n if (currentDepth >= maxDepth) {\n return '[Nested Object]';\n }\n \n if (obj === null || obj === undefined) {\n return '';\n }\n \n if (Array.isArray(obj)) {\n if (obj.length === 0) return '[]';\n return `[${obj.length} items]`;\n }\n \n const lines: string[] = [];\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) {\n lines.push(`${key}: `);\n } else if (typeof value === 'object') {\n lines.push(`${key}: ${formatNestedObject(value, currentDepth + 1, maxDepth)}`);\n } else {\n lines.push(`${key}: ${value}`);\n }\n }\n \n return lines.join(', ');\n}\n\n/**\n * Get border characters based on style\n */\nfunction getBorderChars(style: 'single' | 'double' | 'rounded' = 'single') {\n return {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n }[style];\n}\n\nfunction getTerminalWidth(): number {\n return process.stdout.columns || 80; // Default to 80 if width cannot be determined\n}\n\n/**\n * Calculate column widths for tabular data display\n * @param data Array of objects to display in table\n * @param columns Configuration for each column to display\n * @param options Additional display options\n * @returns Object with calculated widths for each column\n */\nexport function calculateColumnWidths<T>(\n data: T[],\n columns: {\n key: keyof T;\n header: string;\n minWidth?: number;\n weight?: number; // Relative weight for distributing remaining space (default: 1)\n fixedWidth?: number; // If set, this column will have exactly this width\n getValue?: (item: T) => string; // Custom accessor for nested properties\n getWidth?: (item: T) => number; // Custom width calculator\n }[],\n options: {\n borderChars?: number; // Characters used for borders per column\n additionalBorderWidth?: number; // Additional border width (outer borders, etc.)\n } = {}\n): { [key: string]: number } {\n const terminalWidth = getTerminalWidth();\n \n // Calculate total border width\n const borderCharsPerColumn = options.borderChars ?? 3; // Default \"| \" + \" \" per column\n const additionalBorderWidth = options.additionalBorderWidth ?? 1; // Default \"|\" at the end\n const totalBorderWidth = additionalBorderWidth + columns.length * borderCharsPerColumn;\n \n const availableContentWidth = terminalWidth - totalBorderWidth;\n \n // Calculate initial widths based on content and minimum requirements\n const initialWidths: { [key: string]: number } = {};\n let totalFixedWidth = 0;\n let totalWeight = 0;\n \n // First pass: Calculate initial widths and total weight\n for (const column of columns) {\n const key = column.key as string;\n \n if (column.fixedWidth !== undefined) {\n initialWidths[key] = column.fixedWidth;\n totalFixedWidth += column.fixedWidth;\n continue;\n }\n \n const minWidth = column.minWidth ?? column.header.length;\n \n let contentWidth: number;\n if (column.getWidth) {\n // Use custom width calculator if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => column.getWidth!(item))\n );\n } else if (column.getValue) {\n // Use custom accessor if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(column.getValue!(item) || '').length)\n );\n } else {\n // Default behavior\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(item[column.key] || '').length)\n );\n }\n \n initialWidths[key] = contentWidth;\n totalFixedWidth += contentWidth;\n totalWeight += column.weight ?? 1;\n }\n \n // Calculate remaining width to distribute\n const remainingWidth = Math.max(0, availableContentWidth - totalFixedWidth);\n \n // If we have remaining width and weights, distribute according to weights\n if (remainingWidth > 0 && totalWeight > 0) {\n for (const column of columns) {\n const key = column.key as string;\n if (column.fixedWidth === undefined && column.weight) {\n const extraWidth = Math.floor(remainingWidth * (column.weight / totalWeight));\n initialWidths[key] += extraWidth;\n }\n }\n }\n \n // If total width would exceed terminal, scale everything down proportionally\n const calculatedTotalWidth = Object.values(initialWidths).reduce((sum, width) => sum + width, 0) + totalBorderWidth;\n \n if (calculatedTotalWidth > terminalWidth) {\n const scale = availableContentWidth / (calculatedTotalWidth - totalBorderWidth);\n \n const finalWidths: { [key: string]: number } = {};\n for (const column of columns) {\n const key = column.key as string;\n const minWidth = column.minWidth ?? column.header.length;\n finalWidths[key] = Math.max(minWidth, Math.floor(initialWidths[key] * scale));\n }\n \n return finalWidths;\n }\n \n return initialWidths;\n}\n\n/**\n * Example of how to use calculateColumnWidths with nested objects\n * @param data Array of objects with nested properties\n * @returns Object with calculated column widths\n */\nexport function calculateNestedTableWidths<T>(\n data: T[],\n columns: Array<{\n key: string; // Output key in the result object\n header: string;\n minWidth: number;\n weight?: number;\n accessor: (item: T) => string; // Function to access the nested property\n }>\n): { [key: string]: number } {\n // Convert to the format expected by calculateColumnWidths\n const columnConfig = columns.map((col, index) => ({\n key: `col_${index}` as keyof T, // Use a unique key for each column\n header: col.header,\n minWidth: col.minWidth,\n weight: col.weight,\n getValue: col.accessor\n }));\n\n // Get the raw widths\n const widths = calculateColumnWidths(data, columnConfig, { borderChars: 3, additionalBorderWidth: 1 });\n \n // Remap to expected keys\n const result: { [key: string]: number } = {};\n columns.forEach((col, index) => {\n result[col.key] = widths[`col_${index}` as string];\n });\n \n return result;\n}\n\n/**\n * Format and display data as a table in the terminal with customizable styling\n * @param data Array of objects to display in table\n * @param options Table display options\n */\nexport function formatTable<T>(\n data: T[],\n options: {\n columns?: Array<{\n key: keyof T | string;\n header?: string;\n minWidth?: number;\n weight?: number;\n accessor?: (item: T) => any;\n formatter?: (value: any) => string;\n enableTextWrapping?: boolean; // Changed from wrapText to enableTextWrapping\n }>;\n includeHeaders?: boolean;\n border?: boolean;\n borderStyle?: 'single' | 'double' | 'rounded';\n headerStyle?: (text: string) => string;\n cellStyle?: (text: string, rowIndex: number, colKey: string) => string;\n enableTextWrapping?: boolean; // Global option to control text wrapping\n keyValueMode?: boolean; // Option to display a single object in key-value rows\n } = {}\n): void {\n // If in key-value mode, transform the data\n if (options.keyValueMode && data.length === 1) {\n const obj = data[0];\n const keyValueData: Array<{key: string, value: any}> = [];\n \n // Generate columns if not provided\n if (!options.columns) {\n options.columns = Object.keys(obj).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1') // Capitalize and add spaces\n }));\n }\n \n // Transform object to key-value rows\n for (const col of options.columns) {\n const key = String(col.key);\n let value;\n \n if (col.accessor) {\n value = col.accessor(obj);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current;\n } else {\n value = obj[col.key as keyof T];\n }\n \n // Apply formatter if provided\n if (col.formatter) {\n value = col.formatter(value);\n }\n \n keyValueData.push({\n key: col.header || key,\n value: value\n });\n }\n \n // Replace data and columns\n data = keyValueData as unknown as T[];\n options.columns = [\n { key: 'key' as keyof T, minWidth: 15 },\n { key: 'value' as keyof T, minWidth: 20 }\n ];\n }\n\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n\n // Default options\n const defaultOptions = {\n includeHeaders: true,\n border: true,\n borderStyle: 'single' as const,\n headerStyle: (text: string) => chalk.bold(text),\n cellStyle: (text: string) => text,\n enableTextWrapping: true // Enable text wrapping by default\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n\n // Auto-generate columns if not provided\n let columns = mergedOptions.columns;\n if (!columns) {\n const sample = data[0];\n columns = Object.keys(sample).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize header\n enableTextWrapping: mergedOptions.enableTextWrapping\n }));\n } else {\n // Ensure all columns have enableTextWrapping property set if not explicitly defined\n columns = columns.map(col => ({\n ...col,\n enableTextWrapping: col.enableTextWrapping !== undefined ? col.enableTextWrapping : mergedOptions.enableTextWrapping\n }));\n }\n\n // Configure border characters based on style\n const borderChars = {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n };\n\n const border = borderChars[mergedOptions.borderStyle];\n\n // Configure column config for width calculation\n const columnConfig = columns.map(col => ({\n key: col.key as keyof T,\n header: col.header || String(col.key),\n minWidth: col.minWidth || 3,\n weight: col.weight,\n enableTextWrapping: col.enableTextWrapping,\n getValue: col.accessor ? \n (item: T) => col.accessor!(item) : \n (item: T) => {\n // Handle dot notation for nested objects\n if (typeof col.key === 'string' && col.key.includes('.')) {\n const parts = col.key.split('.');\n let value: any = item;\n for (const part of parts) {\n if (value === null || value === undefined) return '';\n value = value[part as keyof typeof value];\n }\n return value ?? '';\n }\n return item[col.key as keyof T] ?? '';\n }\n }));\n\n // Calculate column widths\n const widths = calculateColumnWidths(data, columnConfig);\n\n // Prepare column and header arrays with proper keys\n const formattedColumns = columns.map((col, index) => ({\n ...col,\n width: widths[columnConfig[index].key as string]\n }));\n\n // Format headers and rows\n const headers = formattedColumns.map(col => col.header || String(col.key));\n \n // Helper to format a row with text wrapping support\n const formatRow = (row: T, rowIndex: number) => {\n // For each column, get the value and wrap it if needed\n const rowData = formattedColumns.map(col => {\n let value;\n if (col.accessor) {\n value = col.accessor(row);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = row;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current ?? '';\n } else {\n value = row[col.key as keyof T] ?? '';\n }\n \n // Format the value\n let displayValue = col.formatter ? col.formatter(value) : String(value || '');\n \n // Wrap text if enabled for this column\n if (col.enableTextWrapping) {\n return {\n lines: wrapText(displayValue, col.width),\n key: String(col.key)\n };\n }\n // Truncate if not wrapping\n return {\n lines: [displayValue.length > col.width ? \n displayValue.substring(0, col.width - 1) + '…' : \n displayValue],\n key: String(col.key)\n };\n });\n \n // Calculate the maximum number of lines in any column for this row\n const maxLines = Math.max(...rowData.map(col => col.lines.length));\n \n // Format each line of the row\n const formattedLines = [];\n for (let lineIndex = 0; lineIndex < maxLines; lineIndex++) {\n const lineContent = rowData.map((col, colIndex) => {\n const content = col.lines[lineIndex] || '';\n return mergedOptions.cellStyle(\n content.padEnd(formattedColumns[colIndex].width), \n rowIndex, \n col.key\n );\n });\n formattedLines.push(lineContent);\n }\n \n return formattedLines;\n };\n\n // Generate table parts\n if (mergedOptions.border) {\n // Top border\n const topBorder = border.topLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.topT) +\n border.topRight;\n console.log(topBorder);\n \n // Headers with possible wrapping\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = border.vertical + \n wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return ' ' + mergedOptions.headerStyle(content.padEnd(header.width)) + ' ';\n }).join(border.vertical) + \n border.vertical;\n console.log(headerLine);\n }\n \n // Header-data separator\n const headerSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(\n border.vertical + \n rowLine.map(cell => ` ${cell} `).join(border.vertical) + \n border.vertical\n );\n });\n \n // Optional: Add a separator between rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n const rowSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(rowSeparator);\n }\n });\n \n // Bottom border\n const bottomBorder = border.bottomLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.bottomT) +\n border.bottomRight;\n console.log(bottomBorder);\n } else {\n // No borders, simpler display\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return mergedOptions.headerStyle(content.padEnd(header.width));\n }).join(' ');\n console.log(headerLine);\n }\n \n // Simple underline for headers\n const headerSeparator = formattedColumns.map(col => \n '─'.repeat(col.width)\n ).join(' ');\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(rowLine.join(' '));\n });\n \n // Add a blank line between multi-line rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n console.log('');\n }\n });\n }\n \n console.log(`Total: ${data.length} rows`);\n}\n\n","import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { getApiKey } from '../utils/credentials';\nimport { logger } from '../utils/logger';\nimport { CLOUD_API_URL, CLI_VERSION } from '../utils/constants';\n\n// Helper function to safely stringify objects that might contain cyclic references\nfunction safeStringify(obj: any): string {\n try {\n return JSON.stringify(obj);\n } catch (error) {\n if (error instanceof Error && error.message.includes('cyclic')) {\n return '[Cyclic Object]';\n }\n return String(obj);\n }\n}\n\nexport class ApiClient {\n private client: AxiosInstance;\n private apiKey: string | null = null;\n\n constructor(baseURL: string) {\n logger.debug(`Creating API client with base URL: ${baseURL}`);\n \n this.client = axios.create({\n baseURL,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `tee-cloud-cli/${CLI_VERSION}`,\n },\n });\n\n // Add request interceptor to include API key\n this.client.interceptors.request.use(async (config) => {\n if (!this.apiKey) {\n this.apiKey = await getApiKey();\n if (!this.apiKey) {\n throw new Error('API key not found. Please set an API key first with \"phala auth login\"');\n }\n logger.debug(`API key loaded: ${this.apiKey.substring(0, 5)}...`);\n }\n \n config.headers['X-API-Key'] = this.apiKey;\n logger.debug(`Making request to: ${config.baseURL}${config.url}`);\n return config;\n });\n\n // Add response interceptor for error handling\n this.client.interceptors.response.use(\n (response) => {\n logger.debug(`Received successful response from: ${response.config.url}`);\n return response;\n },\n (error) => {\n if (error.response) {\n const { status, data } = error.response;\n \n logger.debug(`Received error response: ${status} - ${safeStringify(data)}`);\n \n if (status === 401) {\n logger.error('Authentication failed. Please check your API key.');\n } else if (status === 403) {\n logger.error('You do not have permission to perform this action.');\n } else if (status === 404) {\n logger.error('Resource not found.');\n } else {\n logger.error(`API Error (${status}): ${data.message || safeStringify(data)}`);\n }\n } else if (error.request) {\n logger.error('No response received from the server. Please check your internet connection.');\n logger.debug(`Request details: ${safeStringify(error.request).substring(0, 200)}...`);\n } else {\n logger.error(`Error: ${error.message}`);\n }\n \n return Promise.reject(error);\n }\n );\n }\n\n async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`GET request to: ${url}`);\n const response = await this.client.get<T>(url, config);\n return response.data;\n } catch (error) {\n logger.debug(`GET request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`POST request to: ${url}`);\n const response = await this.client.post<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`POST request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`PUT request to: ${url}`);\n const response = await this.client.put<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`PUT request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`DELETE request to: ${url}`);\n const response = await this.client.delete<T>(url, config);\n return response.data;\n } catch (error) {\n logger.debug(`DELETE request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async patch<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`PATCH request to: ${url}`);\n const response = await this.client.patch<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`PATCH request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n}\n\n// Create and export a singleton instance\nlogger.debug(`Initializing API client with URL: ${CLOUD_API_URL}`);\nexport const apiClient = new ApiClient(CLOUD_API_URL); ","// API URLs\nexport const CLOUD_API_URL = process.env.CLOUD_API_URL || 'https://cloud-api.phala.network';\nexport const CLOUD_URL = process.env.CLOUD_URL || 'https://cloud.phala.network';\n\n// CLI Version\nexport const CLI_VERSION = '0.0.1';\n\n// Docker Hub API\nexport const DOCKER_HUB_API_URL = 'https://hub.docker.com/v2';\n\n// TEE Simulator\nexport const TEE_SIMULATOR = 'phalanetwork/tappd-simulator:latest';\n\n// Default resource configurations\nexport const DEFAULT_VCPU = 2;\nexport const DEFAULT_MEMORY = 4096; // MB\nexport const DEFAULT_DISK_SIZE = 40; // GB\n\n// Default TEEPod ID\nexport const DEFAULT_TEEPOD_ID = '3';\nexport const DEFAULT_IMAGE = 'dstack-0.3.5';\n\n// API Endpoints\nexport const API_ENDPOINTS = {\n // Auth\n USER_INFO: '/api/v1/auth/me',\n\n // TEEPods\n TEEPODS: '/api/v1/teepods/available',\n TEEPOD_IMAGES: (teepodId: string) => `/api/v1/teepods/${teepodId}/images`,\n \n // CVMs\n CVMS: (userId: number) => `/api/v1/cvms?user_id=${userId}`,\n CVM_BY_APP_ID: (appId: string) => `/api/v1/cvms/app_${appId}`,\n CVM_NETWORK: (appId: string) => `/api/v1/cvms/app_${appId}/network`,\n CVM_START: (appId: string) => `/api/v1/cvms/app_${appId}/start`,\n CVM_STOP: (appId: string) => `/api/v1/cvms/app_${appId}/stop`,\n CVM_RESTART: (appId: string) => `/api/v1/cvms/app_${appId}/restart`,\n CVM_LOGS: (appId: string) => `/api/v1/cvms/app_${appId}/logs`,\n CVM_FROM_CONFIGURATION: '/api/v1/cvms/from_cvm_configuration',\n CVM_PUBKEY: '/api/v1/cvms/pubkey/from_cvm_configuration',\n CVM_UPGRADE: (appId: string) => `/api/v1/cvms/app_${appId}/compose`,\n CVM_ATTESTATION: (appId: string) => `/api/v1/cvms/app_${appId}/attestation`,\n CVM_RESIZE: (appId: string) => `/api/v1/cvms/app_${appId}/resources`,\n};\n\nexport const DOCKER_COMPOSE_ELIZA_V2_TEMPLATE = `version: '3.8'\nservices:\n postgres:\n image: postgres:15\n environment:\n - POSTGRES_PASSWORD=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_DB=eliza\n volumes:\n - postgres-data:/var/lib/postgresql/data\n ports:\n - \"127.0.0.1:5432:5432\"\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 5s\n timeout: 5s\n retries: 5\n restart: always\n eliza:\n image: {{imageName}}\n container_name: elizav2\n command: bun run start\n stdin_open: true\n tty: true\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n{{#each envVars}} - {{{this}}}\n{{/each}}\n ports:\n - \"3000:3000\"\n - \"5173:5173\"\n depends_on:\n postgres:\n condition: service_healthy\n restart: always\n networks:\n - eliza-network\n\n\nnetworks:\n eliza-network:\n driver: bridge\n\nvolumes:\n postgres-data:`;\n\nexport const DOCKER_COMPOSE_BASIC_TEMPLATE = `version: '3.8'\nservices:\n app:\n image: {{imageName}}\n container_name: app\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n{{#each envVars}} - {{{this}}}\n{{/each}}\n restart: always\n`","import { z } from 'zod';\nimport { ZodDecimal as zodDecimal } from '../utils/types';\n// Docker Config Schema\nexport const dockerConfigSchema = z.object({\n password: z.string(),\n registry: z.string().nullable(),\n username: z.string()\n});\n\n// Compose File Schema\nexport const composeFileSchema = z.object({\n docker_compose_file: z.string(),\n docker_config: dockerConfigSchema.optional(),\n features: z.array(z.string()),\n kms_enabled: z.boolean(),\n manifest_version: z.number(),\n name: z.string(),\n public_logs: z.boolean(),\n public_sysinfo: z.boolean(),\n runner: z.string().optional(),\n salt: z.string().nullable().optional(),\n tproxy_enabled: z.boolean(),\n version: z.string().optional()\n});\n\n// Configuration Schema\nexport const configurationSchema = z.object({\n name: z.string(),\n image: z.string(),\n compose_file: composeFileSchema,\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n ports: z.array(z.any())\n});\n\n// Hosted Schema\nexport const hostedSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.string(),\n uptime: z.string(),\n app_url: z.string(),\n app_id: z.string(),\n instance_id: z.string(),\n configuration: configurationSchema,\n exited_at: z.string(),\n boot_progress: z.string(),\n boot_error: z.string(),\n shutdown_progress: z.string(),\n image_version: z.string()\n});\n\n// Managed User Schema\nexport const managedUserSchema = z.object({\n id: z.number(),\n username: z.string()\n});\n\n// Node Schema\nexport const nodeSchema = z.object({\n id: z.number(),\n name: z.string()\n});\n\n// CVM Instance Schema\nexport const cvmInstanceSchema = z.object({\n hosted: hostedSchema,\n name: z.string(),\n managed_user: managedUserSchema,\n node: nodeSchema,\n listed: z.boolean(),\n status: z.string(),\n in_progress: z.boolean(),\n dapp_dashboard_url: z.string().nullable(),\n syslog_endpoint: z.string(),\n allow_upgrade: z.boolean()\n});\n\n// POST request CVM Response Schema\nexport const postCvmResponseSchema = z.object({\n id: z.number(),\n name: z.string(),\n status: z.string(),\n teepod_id: z.number().nullable(),\n teepod: z.object({\n id: z.number(),\n name: z.string()\n }).nullable(),\n user_id: z.number(),\n app_id: z.string(),\n vm_uuid: z.string().nullable(),\n instance_id: z.string().nullable(),\n app_url: z.string().nullable(),\n base_image: z.string(),\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n manifest_version: z.number(),\n version: z.string(),\n runner: z.string(),\n docker_compose_file: z.string(),\n features: z.array(z.string()).nullable(),\n created_at: z.string(),\n encrypted_env_pubkey: z.string()\n});\n\n// Get Pubkey From CVM Response Schema\nexport const getPubkeyFromCvmResponseSchema = z.object({\n app_env_encrypt_pubkey: z.string(),\n app_id_salt: z.string()\n});\n\n// Get CVM By App ID Response Schema\nexport const getCvmByAppIdResponseSchema = z.object({\n id: z.number(),\n teepod_id: z.number().nullable(),\n teepod: z.object({\n id: z.number(),\n name: z.string()\n }).nullable(),\n name: z.string(),\n status: z.string(),\n in_progress: z.boolean(),\n app_id: z.string(),\n vm_uuid: z.string(),\n instance_id: z.string(),\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n base_image: z.string(),\n encrypted_env_pubkey: z.string(),\n listed: z.boolean(),\n project_id: z.string(),\n project_type: z.string().nullable()\n});\n\n// Get User Info Response Schema\nexport const getUserInfoResponseSchema = z.object({\n username: z.string(),\n email: z.string(),\n credits: zodDecimal.create({ coerce: true }),\n role: z.string(),\n avatar: z.string(),\n flag_reset_password: z.boolean(),\n team_name: z.string(),\n team_tier: z.string(),\n trial_ended_at: z.string().nullable()\n});\n\n// Get CVMs By User ID Response Schema\nexport const getCvmsByUserIdResponseSchema = z.array(cvmInstanceSchema);\n\n// Upgrade CVM Response Schema\nexport const upgradeCvmResponseSchema = z.object({\n detail: z.string()\n});\n\n// Encrypted Env Item Schema\nexport const encryptedEnvItemSchema = z.object({\n key: z.string(),\n value: z.string()\n});\n\n// Image Schema\nexport const imageSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n version: z.array(z.number()).optional(),\n is_dev: z.boolean().optional(),\n rootfs_hash: z.string().optional(),\n shared_ro: z.boolean().optional(),\n cmdline: z.string().optional(),\n kernel: z.string().optional(),\n initrd: z.string().optional(),\n hda: z.string().nullable().optional(),\n rootfs: z.string().optional(),\n bios: z.string().optional()\n});\n\n// TEEPod Schema with extended properties\nexport const teepodSchema = z.object({\n teepod_id: z.number().nullable(),\n name: z.string(),\n listed: z.boolean(),\n resource_score: z.number(),\n remaining_vcpu: z.number(),\n remaining_memory: z.number(),\n remaining_cvm_slots: z.number(),\n images: z.array(imageSchema).optional()\n});\n\n// Capacity Schema\nexport const capacitySchema = z.object({\n max_instances: z.number().nullable(),\n max_vcpu: z.number().nullable(),\n max_memory: z.number().nullable(),\n max_disk: z.number().nullable()\n});\n\n// TeepodResponse Schema\nexport const teepodResponseSchema = z.object({\n tier: z.string(),\n capacity: capacitySchema,\n nodes: z.array(teepodSchema)\n});\n\n// Get CVM Network Response Schema\nexport const getCvmNetworkResponseSchema = z.object({\n is_online: z.boolean(),\n is_public: z.boolean(),\n error: z.string().nullable(),\n internal_ip: z.string(),\n latest_handshake: z.string(),\n public_urls: z.array(z.object({\n app: z.string(),\n instance: z.string()\n })),\n});\n\n// Type exports\nexport type DockerConfig = z.infer<typeof dockerConfigSchema>;\nexport type ComposeFile = z.infer<typeof composeFileSchema>;\nexport type Configuration = z.infer<typeof configurationSchema>;\nexport type Hosted = z.infer<typeof hostedSchema>;\nexport type ManagedUser = z.infer<typeof managedUserSchema>;\nexport type Node = z.infer<typeof nodeSchema>;\nexport type CvmInstance = z.infer<typeof cvmInstanceSchema>;\nexport type PostCvmResponse = z.infer<typeof postCvmResponseSchema>;\nexport type GetPubkeyFromCvmResponse = z.infer<typeof getPubkeyFromCvmResponseSchema>;\nexport type GetCvmByAppIdResponse = z.infer<typeof getCvmByAppIdResponseSchema>;\nexport type GetUserInfoResponse = z.infer<typeof getUserInfoResponseSchema>;\nexport type GetCvmsByUserIdResponse = z.infer<typeof getCvmsByUserIdResponseSchema>;\nexport type UpgradeCvmResponse = z.infer<typeof upgradeCvmResponseSchema>;\nexport type EncryptedEnvItem = z.infer<typeof encryptedEnvItemSchema>;\nexport type TEEPod = z.infer<typeof teepodSchema>;\nexport type Image = z.infer<typeof imageSchema>;\nexport type Capacity = z.infer<typeof capacitySchema>;\nexport type TeepodResponse = z.infer<typeof teepodResponseSchema>;\nexport type CvmAttestationResponse = z.infer<typeof cvmAttestationResponseSchema>;\nexport type GetCvmNetworkResponse = z.infer<typeof getCvmNetworkResponseSchema>;\n/**\n * Certificate naming information\n */\nexport interface CertificateNameInfo {\n common_name: string | null;\n organization: string | null;\n country: string | null;\n state?: string | null;\n locality?: string | null;\n}\n\n/**\n * Certificate data structure\n */\nexport interface CertificateInfo {\n subject: CertificateNameInfo;\n issuer: CertificateNameInfo;\n serial_number: string;\n not_before: string;\n not_after: string;\n version: string;\n fingerprint: string;\n signature_algorithm: string;\n sans: string | null;\n is_ca: boolean;\n position_in_chain: number;\n quote: string | null;\n}\n\n/**\n * Event log entry\n */\nexport interface TCBEventLogEntry {\n imr: number;\n event_type: number;\n digest: string;\n event: string;\n event_payload: string;\n}\n\n/**\n * Trusted Computing Base (TCB) information\n */\nexport interface TCBInfo {\n mrtd: string;\n rootfs_hash: string;\n rtmr0: string;\n rtmr1: string;\n rtmr2: string;\n rtmr3: string;\n event_log: TCBEventLogEntry[];\n}\n\nexport const cvmAttestationResponseSchema = z.object({\n is_online: z.boolean(),\n is_public: z.boolean(),\n error: z.string().nullable(),\n app_certificates: z.array(z.object({\n subject: z.object({\n common_name: z.string().nullable(),\n organization: z.string().nullable(),\n country: z.string().nullable(),\n state: z.string().nullable().optional(),\n locality: z.string().nullable().optional()\n }),\n issuer: z.object({\n common_name: z.string().nullable(),\n organization: z.string().nullable(),\n country: z.string().nullable()\n }),\n serial_number: z.string(),\n not_before: z.string(),\n not_after: z.string(),\n version: z.string(),\n fingerprint: z.string(),\n signature_algorithm: z.string(),\n sans: z.string().nullable(),\n is_ca: z.boolean(),\n position_in_chain: z.number(),\n quote: z.string().nullable()\n })).nullable(),\n tcb_info: z.object({\n mrtd: z.string(),\n rootfs_hash: z.string(),\n rtmr0: z.string(),\n rtmr1: z.string(),\n rtmr2: z.string(),\n rtmr3: z.string(),\n event_log: z.array(z.object({\n imr: z.number(),\n event_type: z.number(),\n digest: z.string(),\n event: z.string(),\n event_payload: z.string()\n }))\n }).nullable(),\n compose_file: z.string().nullable()\n});","import {\n INVALID,\n ParseContext,\n ParseInput,\n ParseReturnType,\n ParseStatus,\n RawCreateParams,\n ZodIssueCode,\n ZodParsedType,\n ZodType,\n ZodTypeDef,\n addIssueToContext,\n z,\n} from 'zod';\n\nexport type ZodDecimalCheck =\n | { kind: 'precision'; value: number; message?: string }\n | { kind: 'wholeNumber'; value: number; message?: string }\n | { kind: 'min'; value: number; inclusive: boolean; message?: string }\n | { kind: 'max'; value: number; inclusive: boolean; message?: string }\n | { kind: 'finite'; message?: string };\n\nconst zodDecimalKind = 'ZodDecimal';\n\nexport interface ZodDecimalDef extends ZodTypeDef {\n checks: ZodDecimalCheck[];\n typeName: typeof zodDecimalKind;\n coerce: boolean;\n}\n\nconst precisionRegex = /(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ZodDecimal extends ZodType<number, ZodDecimalDef, any> {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n _parse(input: ParseInput): ParseReturnType<number> {\n // detect decimal js object\n if (input.data !== null && typeof input.data === 'object' && 'toNumber' in input.data) {\n input.data = input.data.toNumber();\n }\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.number,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n\n let ctx: undefined | ParseContext = undefined;\n const status = new ParseStatus();\n\n for (const check of this._def.checks) {\n if (check.kind === 'precision') {\n const parts = input.data.toString().match(precisionRegex);\n const decimals = Math.max(\n (parts[1] ? parts[1].length : 0) - (parts[2] ? parseInt(parts[2], 10) : 0),\n 0\n );\n if (decimals > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.custom,\n message: check.message,\n params: {\n precision: check.value,\n },\n });\n status.dirty();\n }\n } else if (check.kind === 'wholeNumber') {\n const wholeNumber = input.data.toString().split('.')[0];\n const tooLong = wholeNumber.length > check.value;\n\n if (tooLong) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.custom,\n message: check.message,\n params: {\n wholeNumber: check.value,\n },\n });\n status.dirty();\n }\n } else if (check.kind === 'min') {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: 'number',\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n } else if (check.kind === 'max') {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: 'number',\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n } else if (check.kind === 'finite') {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n }\n\n return { status: status.value, value: input.data };\n }\n\n static create = (params?: RawCreateParams & { coerce?: true }): ZodDecimal => {\n return new ZodDecimal({\n checks: [],\n typeName: zodDecimalKind,\n coerce: params?.coerce ?? false,\n });\n };\n\n protected setLimit(\n kind: 'min' | 'max',\n value: number,\n inclusive: boolean,\n message?: string\n ): ZodDecimal {\n return new ZodDecimal({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message,\n },\n ],\n });\n }\n\n _addCheck(check: ZodDecimalCheck): ZodDecimal {\n return new ZodDecimal({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n\n lte(value: number, message?: string): ZodDecimal {\n return this.setLimit('max', value, true, message);\n }\n\n lt(value: number, message?: string): ZodDecimal {\n return this.setLimit('max', value, false, message);\n }\n max = this.lte;\n\n gt(value: number, message?: string): ZodDecimal {\n return this.setLimit('min', value, false, message);\n }\n gte(value: number, message?: string): ZodDecimal {\n return this.setLimit('min', value, true, message);\n }\n\n min = this.gte;\n\n precision(value: number, message?: string): ZodDecimal {\n return this._addCheck({\n kind: 'precision',\n value,\n message,\n });\n }\n wholeNumber(value: number, message?: string): ZodDecimal {\n return this._addCheck({\n kind: 'wholeNumber',\n value,\n message,\n });\n }\n\n get minValue() {\n let min: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'min') {\n if (min === null || ch.value > min) min = ch.value;\n }\n }\n return min;\n }\n\n get maxValue() {\n let max: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'max') {\n if (max === null || ch.value < max) max = ch.value;\n }\n }\n return max;\n }\n\n positive(message?: string) {\n return this._addCheck({\n kind: 'min',\n value: 0,\n inclusive: false,\n message,\n });\n }\n\n negative(message?: string) {\n return this._addCheck({\n kind: 'max',\n value: 0,\n inclusive: false,\n message,\n });\n }\n\n nonpositive(message?: string) {\n return this._addCheck({\n kind: 'max',\n value: 0,\n inclusive: true,\n message,\n });\n }\n\n nonnegative(message?: string) {\n return this._addCheck({\n kind: 'min',\n value: 0,\n inclusive: true,\n message,\n });\n }\n\n finite(message?: string) {\n return this._addCheck({\n kind: 'finite',\n message,\n });\n }\n\n safe(message?: string) {\n return this._addCheck({\n kind: 'min',\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message,\n })._addCheck({\n kind: 'max',\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message,\n });\n }\n\n get isFinite() {\n let max: number | null = null;\n let min: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'finite') {\n return true;\n } else if (ch.kind === 'min') {\n if (min === null || ch.value > min) min = ch.value;\n } else if (ch.kind === 'max') {\n if (max === null || ch.value < max) max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\n\n// Docker Compose Template Schema\nexport const ComposeTemplateSchema = z.object({\n template: z.string().min(1, \"Template cannot be empty\")\n});\n\nexport type ComposeTemplate = z.infer<typeof ComposeTemplateSchema>;","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '../utils/constants';\nimport { GetUserInfoResponse, getUserInfoResponseSchema } from './types';\nimport { logger } from '../utils/logger';\n\n// Helper function to safely stringify objects that might contain cyclic references\nfunction safeStringify(obj: any): string {\n try {\n return JSON.stringify(obj);\n } catch (error) {\n if (error instanceof Error && error.message.includes('cyclic')) {\n return '[Cyclic Object]';\n }\n return String(obj);\n }\n}\n\n/**\n * Get user information\n * @returns User information\n */\nexport async function getUserInfo(): Promise<GetUserInfoResponse> {\n try {\n logger.debug(`Fetching user info from ${API_ENDPOINTS.USER_INFO}`);\n const response = await apiClient.get<any>(API_ENDPOINTS.USER_INFO);\n logger.debug(`Received response: ${safeStringify(response)}`);\n \n // Try to parse the response with the schema\n try {\n return getUserInfoResponseSchema.parse(response);\n } catch (parseError) {\n logger.error(`Failed to parse user info response: ${parseError}`);\n logger.debug(`Response structure: ${safeStringify(response)}`);\n throw parseError;\n }\n } catch (error) {\n logger.error(`Failed to get user info: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error(`Failed to get user info: ${error instanceof Error ? error.message : String(error)}`);\n }\n}","import { Command } from 'commander';\nimport { removeApiKey } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\n\nexport const logoutCommand = new Command()\n .name('logout')\n .description('Remove the stored API key')\n .action(async () => {\n try {\n await removeApiKey();\n logger.success('API key removed successfully');\n } catch (error) {\n logger.error(`Failed to remove API key: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { getApiKey } from '@/src/utils/credentials';\nimport { getUserInfo } from '@/src/api/auth';\nimport { logger } from '@/src/utils/logger';\n\nexport const statusCommand = new Command()\n .name('status')\n .description('Check authentication status')\n .option('-j, --json', 'Output in JSON format')\n .option('-d, --debug', 'Enable debug output')\n .action(async (options) => {\n try {\n // Enable debug mode if requested\n if (options.debug) {\n process.env.DEBUG = 'true';\n }\n \n const apiKey = await getApiKey();\n \n if (!apiKey) {\n logger.warn('Not authenticated. Please set an API key with \"phala auth login\"');\n return;\n }\n \n logger.debug(`Using API key: ${apiKey.substring(0, 5)}...`);\n const spinner = logger.startSpinner('Checking authentication status');\n \n try {\n const userInfo = await getUserInfo();\n spinner.stop(true);\n \n if (options.json) {\n console.log(JSON.stringify(userInfo, null, 2));\n return;\n }\n \n logger.break();\n logger.success(`Authenticated as ${userInfo.username}`);\n \n // Create a simple object\n const tableData = {\n 'Username': userInfo.username,\n 'Email': userInfo.email,\n 'Role': userInfo.role,\n 'Team': `${userInfo.team_name} (${userInfo.team_tier})`,\n 'Credits': `$${userInfo.credits}`\n };\n \n if (userInfo.trial_ended_at) {\n tableData['Trial Ended At'] = userInfo.trial_ended_at;\n }\n \n // Display the table\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n } catch (error) {\n spinner.stop(false);\n logger.error('Authentication failed. Your API key may be invalid or expired.');\n logger.info('Please set a new API key with \"phala auth login\"');\n \n if (options.debug) {\n logger.debug(`Error details: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to check authentication status: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { loginCommand } from './login';\nimport { buildCommand } from './build';\nimport { pushCommand } from './push';\nimport { generateCommand } from './generate';\n\nexport const dockerCommands = new Command()\n .name('docker')\n .description('Login to Docker Hub and manage Docker images')\n .addCommand(loginCommand)\n .addCommand(buildCommand)\n .addCommand(pushCommand)\n .addCommand(generateCommand);\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { saveDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport prompts from 'prompts';\n\nexport const loginCommand = new Command()\n .name('login')\n .description('Login to Docker Hub')\n .option('-u, --username <username>', 'Docker Hub username')\n .option('-p, --password <password>', 'Docker Hub password')\n .option('-r, --registry <registry>', 'Docker registry URL')\n .action(async (options) => {\n try {\n let username = options.username;\n let password = options.password;\n const registry = options.registry;\n \n // If no username is provided, prompt for it\n if (!username) {\n logger.info('First we need your Docker Hub username to check if you are already logged in.');\n\n const response = await prompts({\n type: 'text',\n name: 'username',\n message: 'Enter your Docker Hub username:',\n validate: value => value.length > 0 ? true : 'Username cannot be empty'\n });\n \n if (!response.username) {\n logger.error('Username is required');\n process.exit(1);\n }\n \n username = response.username;\n }\n\n // Check if Docker is already logged in\n const dockerService = new DockerService('', username, registry);\n const loggedIn = await dockerService.login(username);\n if (loggedIn) {\n logger.success(`${username} is logged in to Docker Hub`);\n // Save credentials\n await saveDockerCredentials({\n username,\n registry: registry || null,\n });\n return;\n }\n \n // If no password is provided, prompt for it\n if (!password) {\n const response = await prompts({\n type: 'password',\n name: 'password',\n message: 'Enter your Docker Hub password:',\n validate: value => value.length > 0 ? true : 'Password cannot be empty'\n });\n \n if (!response.password) {\n logger.error('Password is required');\n process.exit(1);\n }\n \n password = response.password;\n }\n \n // Login to Docker Hub\n const success = await dockerService.login(username, password, registry);\n \n if (!success) {\n logger.error('Failed to login to Docker Hub');\n process.exit(1);\n }\n \n // Save credentials\n await saveDockerCredentials({\n username,\n registry: registry || null\n });\n \n logger.success('Logged in to Docker Hub successfully');\n } catch (error) {\n logger.error(`Failed to login to Docker Hub: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from './logger';\nimport { DOCKER_COMPOSE_BASIC_TEMPLATE, DOCKER_COMPOSE_ELIZA_V2_TEMPLATE } from './constants';\nimport { getDockerCredentials } from './credentials';\nimport Handlebars from 'handlebars';\nimport { exec, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport os from 'node:os';\nimport { validateFileExists } from './prompts';\nimport { ComposeTemplateSchema } from './types';\nimport { deleteSimulatorEndpointEnv, setSimulatorEndpointEnv } from './simulator';\nconst execAsync = promisify(exec);\n\nconst LOGS_DIR = '.phala-cloud/logs';\nconst COMPOSE_FILES_DIR = '.phala-cloud/compose';\nconst MAX_CONSOLE_LINES = 10;\n\nexport class DockerService {\n private username: string;\n private image: string;\n private registry: string;\n\n constructor(image: string, username?: string, registry?: string) {\n this.image = image;\n this.username = username || '';\n this.registry = registry || '';\n }\n\n private ensureLogsDir(): void {\n const logsPath = path.resolve(LOGS_DIR);\n if (!fs.existsSync(logsPath)) {\n fs.mkdirSync(logsPath, { recursive: true });\n }\n }\n\n private getLogFilePath(operation: string, image?: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return path.resolve(LOGS_DIR, `${image || this.image}-${operation}-${timestamp}.log`);\n }\n\n private getSystemArchitecture(): string {\n const arch = os.arch();\n switch (arch) {\n case 'arm':\n case 'arm64':\n return 'arm64';\n case 'x64':\n return 'amd64';\n default:\n return arch;\n }\n }\n\n private spawnProcess(command: string, args: string[], operation: string, image?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args);\n // Ensure logs directory exists before creating write stream\n this.ensureLogsDir();\n\n const logFile = this.getLogFilePath(operation, image);\n\n const logStream = fs.createWriteStream(logFile, { flags: 'a' });\n const consoleBuffer: string[] = [];\n\n const processOutput = (data: Buffer, isError: boolean = false) => {\n const lines = data.toString().split('\\n');\n\n // Write to log file\n logStream.write(data);\n\n // Update console buffer\n lines.forEach(line => {\n if (line.trim()) {\n consoleBuffer.push(line);\n // Keep only the last MAX_CONSOLE_LINES lines\n if (consoleBuffer.length > MAX_CONSOLE_LINES) {\n consoleBuffer.shift();\n }\n\n // Clear console and print the buffer\n console.clear();\n console.log(`Latest ${MAX_CONSOLE_LINES} lines (full log at ${logFile}):`);\n console.log('-'.repeat(50));\n consoleBuffer.forEach(bufferedLine => {\n if (isError) {\n console.error(bufferedLine);\n } else {\n console.log(bufferedLine);\n }\n });\n }\n });\n };\n\n proc.stdout.on('data', (data) => processOutput(data));\n proc.stderr.on('data', (data) => processOutput(data, true));\n\n proc.on('close', (code) => {\n logStream.end();\n if (code === 0) {\n console.log(`\\nOperation completed. Full log available at: ${logFile}`);\n resolve();\n } else {\n reject(new Error(`Process exited with code ${code}. Check log file: ${logFile}`));\n }\n });\n\n proc.on('error', (err) => {\n logStream.end();\n reject(err);\n });\n });\n }\n\n /**\n * Set Docker credentials\n * @param username Docker username\n * @param registry Docker registry\n */\n setCredentials(username: string, registry?: string): void {\n this.username = username;\n if (registry) {\n this.registry = registry;\n }\n }\n\n /**\n * Build a Docker image\n * @param dockerfile Path to Dockerfile\n * @param tag Tag for the image\n * @returns Success status\n */\n async buildImage(dockerfile: string, tag: string): Promise<boolean> {\n try {\n const arch = this.getSystemArchitecture();\n const fullImageName = `${this.username}/${this.image}:${tag}`;\n\n const spinner = logger.startSpinner(`Building Docker image ${this.username}/${this.image}:${tag}`);\n\n // Ensure the Dockerfile exists\n validateFileExists(dockerfile);\n\n const buildArgs = ['build', '-t', fullImageName, '-f', dockerfile];\n\n if (arch === 'arm64') {\n console.log('Detected arm64 architecture, using --platform linux/amd64');\n buildArgs.push('--platform', 'linux/amd64');\n }\n\n // Build the image\n buildArgs.push('.');\n\n await this.spawnProcess('docker', buildArgs, 'build', this.image);\n\n spinner.stop(true, `Docker image ${fullImageName} built successfully`);\n return true;\n } catch (error) {\n logger.error(`Failed to build Docker image: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Push a Docker image to Docker Hub\n * @param imageName Full image name (e.g. username/image:tag)\n * @returns Success status\n */\n async pushImage(imageName: string): Promise<boolean> {\n try {\n const spinner = logger.startSpinner(`Pushing Docker image ${imageName} to Docker Hub`);\n\n // Check if user is logged in\n const credentials = await getDockerCredentials();\n if (!credentials) {\n spinner.stop(false);\n throw new Error('Docker credentials not found. Please log in first with \"phala docker login\"');\n }\n\n const fullImageName = imageName;\n console.log(`Pushing image ${fullImageName} to Docker Hub...`);\n\n await this.spawnProcess('docker', ['push', fullImageName], 'push', imageName.replace(/.*\\/+(\\w+):.*$/g, '$1'));\n\n spinner.stop(true, `Docker image ${fullImageName} pushed successfully`);\n return true;\n } catch (error) {\n logger.error(`Failed to push Docker image: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n\n /**\n * Login to Docker Hub\n * @param username Docker username\n * @param password Docker password\n * @param registry Docker registry\n * @returns Success status\n */\n async login(username: string, password?: string, registry?: string): Promise<boolean> {\n try {\n const spinner = logger.startSpinner(`Logging in to Docker Hub as ${username}`);\n\n // Check if already logged in\n const loggedIn = await this.checkLogin();\n if (loggedIn) {\n spinner.stop(true, `Logged in as ${username}`);\n this.setCredentials(username, registry);\n return true;\n }\n\n // Login to Docker\n await execa('docker', [\n 'login',\n ...(registry ? [registry] : []),\n '-u',\n username,\n '--password-stdin'\n ], {\n input: password\n });\n\n spinner.stop(true, 'Logged in to Docker Hub successfully');\n this.setCredentials(username, registry);\n return true;\n } catch (error) {\n logger.error(`Failed to login to Docker Hub: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Check if Docker is logged in\n * @returns Success status\n */\n async checkLogin(): Promise<boolean> {\n try {\n // Create a promise that rejects after a timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error('Docker login check timed out')), 5000);\n });\n \n // Create the actual check promise\n const checkPromise = execa('docker', ['login']).then(result => {\n return result.stdout.includes('Login Succeeded');\n });\n \n // Race the promises - whichever finishes first wins\n return await Promise.race([checkPromise, timeoutPromise]) as boolean;\n } catch (error) {\n logger.debug(`Docker login check failed: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Build a Docker Compose file\n * @param imageName Name of the image\n * @param envFile Optional path to environment file\n * @param version Version of the template to use\n * @returns Path to the generated Docker Compose file\n */\n async buildComposeFile(imageName: string, envFile?: string, templateType?: string): Promise<string> {\n if (!this.username) {\n throw new Error('Docker Hub username is required for building compose file');\n }\n\n const template = (templateType === 'eliza') ? DOCKER_COMPOSE_ELIZA_V2_TEMPLATE : DOCKER_COMPOSE_BASIC_TEMPLATE;\n\n // Validate template structure\n const validatedTemplate = ComposeTemplateSchema.parse({ template });\n\n // Ensure compose files directory exists\n const composePath = COMPOSE_FILES_DIR;\n \n // Create directory if it doesn't exist\n if (!fs.existsSync(composePath)) {\n logger.info(`Creating directory: ${composePath}`);\n fs.mkdirSync(composePath, { recursive: true });\n }\n\n let envVars: string[] = [];\n \n // Only parse env file if it's provided\n if (envFile) {\n // Parse env file to get variable names\n const envContent = fs.readFileSync(envFile, 'utf-8');\n envVars = envContent\n .split('\\n')\n .filter(line => line && !line.startsWith('#'))\n .map(line => {\n // Remove inline comments\n const commentIndex = line.indexOf('#');\n if (commentIndex > 0) {\n line = line.substring(0, commentIndex).trim();\n }\n return line.trim();\n })\n .filter(line => line.includes('='))\n .map(line => {\n const [key, value] = line.split('=', 2);\n const trimmedKey = key.trim();\n const trimmedValue = value ? value.trim() : '';\n\n // Skip empty values\n if (trimmedValue === '') {\n return null;\n }\n\n // Keep the original key without any transformation\n return `${trimmedKey}=${trimmedKey}`; // Create KEY=KEY format\n })\n .filter(Boolean as any); // Remove null entries\n }\n\n // Create full image name with username\n const fullImageName = imageName;\n\n // Compile template with data\n const compiledTemplate = Handlebars.compile(validatedTemplate.template, { noEscape: true });\n const composeContent = compiledTemplate({\n imageName: fullImageName,\n envVars: envVars.map(env => env.replace(/=.*/, '=\\${' + env.split('=')[0] + '}'))\n });\n\n // Write the docker-compose file with standardized name in the compose directory\n const composeFile = path.join(\n composePath,\n `${imageName.replace(/.*\\/+(\\w+):.*$/g, \"$1\")}-tee-compose.yaml`,\n );\n fs.writeFileSync(composeFile, composeContent);\n\n logger.success(`Backup of docker compose file created at: ${composeFile}`);\n return composeFile;\n }\n\n /**\n * Run a Docker Compose file locally\n * @param composePath Path to Docker Compose file\n * @param envFile Path to environment file\n * @returns Success status\n */\n async runComposeLocally(composePath: string, envFile?: string): Promise<boolean> {\n try {\n // TODO: Update log when optimized simulator is implemented\n const spinner = logger.startSpinner(`Running Docker Compose file at ${composePath}`);\n\n // Ensure the Docker Compose file exists\n validateFileExists(composePath);\n\n // Build the command arguments\n const composeArgs = [\n '-f',\n composePath,\n 'up',\n '-d'\n ];\n\n // Only add env-file if it's provided\n if (envFile) {\n // Ensure the environment file exists\n validateFileExists(envFile);\n composeArgs.splice(2, 0, '--env-file', envFile);\n }\n\n // Run the Docker Compose file\n await execAsync(`docker compose ${composeArgs.join(' ')}`);\n\n spinner.stop(true, 'Docker Compose file running successfully');\n return true;\n } catch (error) {\n logger.error(`Failed to run Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Run the TEE simulator\n * @param image Simulator image\n * @returns Success status\n */\n async runSimulator(image: string, port: string): Promise<boolean> {\n try {\n logger.info(`Running TEE simulator with image ${image}`);\n\n logger.info('Pulling latest simulator image...');\n await execAsync(`docker pull ${image}`);\n\n logger.info('Starting simulator in background...');\n const { stdout } = await execAsync(`docker run -d --name tee-simulator --rm -p ${port}:${port} ${image}`);\n const containerId = stdout.trim();\n\n logger.success(`TEE simulator running successfully. Container ID: ${containerId}`);\n logger.break();\n logger.break();\n logger.info('Useful commands:');\n logger.info(`- View logs: docker logs -f ${containerId}`);\n logger.info(`- Stop simulator: docker stop ${containerId}`);\n\n setSimulatorEndpointEnv(`http://localhost:${port}`);\n \n return true;\n } catch (error) {\n logger.error(`Failed to run TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Stop the TEE simulator\n * @returns Success status\n */\n async stopSimulator(): Promise<boolean> {\n try {\n const spinner = logger.startSpinner('Stopping TEE simulator...');\n\n // Stop the simulator\n await execAsync('docker stop tee-simulator');\n await deleteSimulatorEndpointEnv();\n\n spinner.stop(true, 'TEE simulator stopped successfully');\n return true;\n } catch (error) {\n logger.error(`Failed to stop TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * List local Docker images and their tags\n * @returns Array of objects with image name and tag\n */\n static async listLocalImages(): Promise<Array<{ imageName: string}>> {\n try {\n // Query Docker for local images in format that outputs repository and tag\n const { stdout } = await execAsync('docker images --format \"{{.Repository}}:{{.Tag}}\"');\n const credentials = await getDockerCredentials();\n const username = credentials?.username;\n // Parse the output and filter out any <none> tags or images\n const imageList = stdout.split('\\n')\n .filter(line => line && !line.includes('<none>'))\n .filter(line => line.includes(`${username}/`))\n .map(line => {\n const imageName = line;\n return { imageName };\n });\n\n return imageList;\n } catch (error) {\n logger.error(`Failed to list local Docker images: ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n }\n}\n\n","import inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from './logger';\n\n/**\n * Validates that a file exists at the given path\n * @param filePath Path to the file to validate\n * @param basePath Optional base path to resolve relative paths against (defaults to process.cwd())\n * @returns True if the file exists, throws an error if not\n * @throws Error if the file does not exist\n */\nexport function validateFileExists(\n filePath: string,\n basePath: string = process.cwd()\n): boolean {\n const resolvedPath = path.resolve(basePath, filePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`File not found at ${resolvedPath}`);\n }\n return true;\n}\n\n/**\n * Prompts the user for a file path and validates that the file exists\n * @param message The prompt message to display\n * @param defaultValue The default value for the prompt\n * @param name The name of the prompt (used as property name in the returned object)\n * @param basePath Optional base path to resolve relative paths against (defaults to process.cwd())\n * @returns The validated file path\n */\nexport async function promptForFile(\n message: string,\n defaultValue: string,\n name = 'file',\n basePath: string = process.cwd()\n): Promise<string> {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name,\n message,\n default: defaultValue,\n validate: (input) => {\n const filePath = path.resolve(basePath, input);\n if (!fs.existsSync(filePath)) {\n return `File not found at ${filePath}`;\n }\n return true;\n }\n }\n ]);\n\n return response[name];\n}\n\nexport function detectFileInCurrentDir(\n possibleFiles: string[],\n logMessage?: string\n): string | undefined {\n for (const file of possibleFiles) {\n const filePath = path.join(process.cwd(), file);\n if (fs.existsSync(filePath)) {\n if (logMessage) {\n logger.info(logMessage.replace('{path}', filePath));\n } else {\n logger.info(`File detected: ${filePath}`);\n }\n return file;\n }\n }\n return undefined;\n}","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { execSync, spawn, type StdioOptions } from 'node:child_process';\nimport * as net from 'node:net';\nimport { logger } from './logger';\n\n// Configuration for simulator\nconst SIMULATOR_CONFIG = {\n version: '0.1.4',\n baseUrl: 'https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4',\n installDir: path.join(os.homedir(), '.phala-cloud', 'tappd-simulator'),\n // Default log file path\n defaultLogPath: path.join(os.homedir(), '.phala-cloud', 'logs', 'tappd-simulator.log'),\n platforms: {\n darwin: {\n filename: 'tappd-simulator-0.1.4-aarch64-apple-darwin.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-aarch64-apple-darwin',\n socketArg: 'unix:/tmp/tappd.sock'\n },\n linux: {\n filename: 'tappd-simulator-0.1.4-x86_64-linux-musl.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-x86_64-linux-musl',\n socketArg: 'unix:/tmp/tappd.sock'\n },\n win32: {\n filename: 'tappd-simulator-0.1.4-x86_64-pc-windows-msvc.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-x86_64-pc-windows-msvc',\n socketArg: '127.0.0.1:8090'\n }\n }\n};\n\n/**\n * Check if the simulator is already installed\n * @returns boolean indicating if simulator is installed\n */\nexport function isSimulatorInstalled(): boolean {\n try {\n // Check if the main installation directory exists\n if (!fs.existsSync(SIMULATOR_CONFIG.installDir)) {\n return false;\n }\n\n // Get platform-specific folder name\n const platform = os.platform() as 'darwin' | 'linux' | 'win32';\n if (!SIMULATOR_CONFIG.platforms[platform]) {\n throw new Error(`Unsupported platform: ${platform}`);\n }\n\n const extractedFolderPath = path.join(\n SIMULATOR_CONFIG.installDir,\n SIMULATOR_CONFIG.platforms[platform].extractedFolder\n );\n\n // Check if the extracted folder exists\n if (!fs.existsSync(extractedFolderPath)) {\n return false;\n }\n\n // Check if the executable exists\n const executableName = platform === 'win32' ? 'tappd-simulator.exe' : 'tappd-simulator';\n const executablePath = path.join(extractedFolderPath, executableName);\n return fs.existsSync(executablePath);\n } catch (error) {\n logger.error('Error checking if simulator is installed:', error);\n return false;\n }\n}\n\n/**\n * Get the current platform\n * @returns The current platform: 'darwin', 'linux', or 'win32'\n * @throws Error if the platform is not supported\n */\nexport function getPlatform(): 'darwin' | 'linux' | 'win32' {\n const platform = os.platform() as 'darwin' | 'linux' | 'win32';\n if (!SIMULATOR_CONFIG.platforms[platform]) {\n throw new Error(`Unsupported platform: ${platform}. Only darwin, linux, and win32 are supported.`);\n }\n return platform;\n}\n\n/**\n * Install the simulator based on the current platform\n * @param progressCallback Optional callback to report progress\n * @returns Promise that resolves when installation is complete\n */\nexport async function installSimulator(\n progressCallback?: (message: string) => void\n): Promise<void> {\n const log = (message: string) => {\n logger.info(message);\n if (progressCallback) progressCallback(message);\n };\n\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n \n // Create installation directory if it doesn't exist\n if (!fs.existsSync(SIMULATOR_CONFIG.installDir)) {\n logger.info(`Creating installation directory at ${SIMULATOR_CONFIG.installDir}`);\n fs.mkdirSync(SIMULATOR_CONFIG.installDir, { recursive: true });\n }\n\n // Change to the installation directory\n process.chdir(SIMULATOR_CONFIG.installDir);\n \n // Download the simulator\n const downloadUrl = `${SIMULATOR_CONFIG.baseUrl}/${platformConfig.filename}`;\n logger.info(`Downloading simulator from ${downloadUrl}`);\n execSync(`wget ${downloadUrl}`, { stdio: 'inherit' });\n \n // Extract the archive\n logger.info(`Extracting ${platformConfig.filename}`);\n execSync(`tar -xvf ${platformConfig.filename}`, { stdio: 'inherit' });\n \n logger.success('Simulator installation completed successfully');\n } catch (error) {\n logger.error('Error installing simulator:', error);\n throw new Error(`Failed to install simulator: ${error}`);\n }\n}\n\n/**\n * Run the simulator\n * @param options Configuration options for running the simulator\n * @returns A child process representing the running simulator\n */\nexport async function runSimulator(options: {\n background?: boolean;\n logToFile?: boolean;\n logFilePath?: string;\n} = {}): Promise<ReturnType<typeof spawn>> {\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n const extractedFolderPath = path.join(\n SIMULATOR_CONFIG.installDir,\n platformConfig.extractedFolder\n );\n \n // Change to the extracted folder directory\n process.chdir(extractedFolderPath);\n \n // Start the simulator\n const executableName = platform === 'win32' ? 'tappd-simulator.exe' : './tappd-simulator';\n \n // Default options\n const runOptions = {\n background: options.background ?? true,\n logToFile: options.logToFile ?? true,\n logFilePath: options.logFilePath ?? SIMULATOR_CONFIG.defaultLogPath\n };\n \n // Create log directory if it doesn't exist\n if (runOptions.logToFile) {\n const logDir = path.dirname(runOptions.logFilePath);\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n logger.info(`Simulator logs will be written to: ${runOptions.logFilePath}`);\n }\n \n logger.info(`Starting simulator with: ${executableName} -l ${platformConfig.socketArg}`);\n \n // Configure stdio based on logging preferences\n let stdio: StdioOptions = 'inherit';\n let outputStream: fs.WriteStream = null;\n \n if (runOptions.logToFile) {\n // Create/open the log file for appending\n outputStream = fs.createWriteStream(runOptions.logFilePath, { flags: 'a' });\n \n // Use the stream for both stdout and stderr\n stdio = ['ignore', outputStream, outputStream];\n }\n \n // Run the simulator\n const simulatorProcess = spawn(executableName, ['-l', platformConfig.socketArg], {\n stdio,\n shell: platform === 'win32', // Use shell on Windows\n detached: runOptions.background // Detach process when running in background\n });\n \n // Write startup entry to log file with timestamp\n if (outputStream) {\n const timestamp = new Date().toISOString();\n outputStream.write(`\\n[${timestamp}] Simulator started\\n`);\n }\n \n // If running in background, unref to allow the parent process to exit\n if (runOptions.background) {\n simulatorProcess.unref();\n logger.success('Simulator is running in the background');\n }\n \n await setSimulatorEndpointEnv();\n return simulatorProcess;\n } catch (error) {\n logger.error('Error running simulator:', error);\n throw new Error(`Failed to run simulator: ${error}`);\n }\n}\n\n/**\n * Ensures the simulator is installed and running\n * @param options Configuration options for running the simulator\n * @returns A promise that resolves to a child process representing the running simulator\n */\nexport async function ensureSimulatorRunning(options: {\n background?: boolean;\n logToFile?: boolean;\n logFilePath?: string;\n} = {}): Promise<ReturnType<typeof spawn>> {\n if (!isSimulatorInstalled()) {\n logger.info('Simulator not installed. Installing now...');\n await installSimulator((message) => logger.info(`Installation progress: ${message}`));\n }\n \n if (await isSimulatorRunning()) {\n logger.info('Simulator is already running');\n return null;\n }\n \n logger.info('Starting simulator...');\n return await runSimulator(options);\n}\n\n/**\n * Check if the simulator is currently running\n * For Unix platforms (Darwin/Linux), checks if the Unix socket exists and is accessible\n * For Windows, tries to connect to the TCP port the simulator should be listening on\n * @returns Promise<boolean> indicating if the simulator is running\n */\nexport async function isSimulatorRunning(): Promise<boolean> {\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n \n if (platform === 'darwin' || platform === 'linux') {\n // For Unix platforms, check if the socket file exists and is accessible\n const socketPath = '/tmp/tappd.sock';\n \n // Check if the socket file exists\n if (!fs.existsSync(socketPath)) {\n return false;\n }\n \n // Try to connect to the socket to verify it's active\n return new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath })\n .on('connect', () => {\n client.end();\n resolve(true);\n })\n .on('error', () => {\n resolve(false);\n });\n \n // Set timeout to avoid hanging if socket exists but nothing is listening\n setTimeout(() => {\n client.end();\n resolve(false);\n }, 1000);\n });\n } \n if (platform === 'win32') {\n // For Windows, try to connect to the TCP port\n const host = '127.0.0.1';\n const port = 8090;\n \n return new Promise<boolean>((resolve) => {\n const client = net.createConnection({ host, port })\n .on('connect', () => {\n client.end();\n resolve(true);\n })\n .on('error', () => {\n resolve(false);\n });\n \n // Set timeout to avoid hanging\n setTimeout(() => {\n client.end();\n resolve(false);\n }, 1000);\n });\n }\n \n return false;\n } catch (error) {\n logger.error('Error checking if simulator is running:', error);\n return false;\n }\n}\n\n/**\n * Stops the simulator if it's running\n * @returns Promise<boolean> indicating if the simulator was successfully stopped\n */\nexport async function stopSimulator(): Promise<boolean> {\n try {\n const platform = getPlatform();\n \n if (!await isSimulatorRunning()) {\n logger.info('Simulator is not running');\n return true;\n }\n \n logger.info('Stopping simulator...');\n \n if (platform === 'win32') {\n // For Windows, find the process listening on port 8080 and kill it\n execSync('for /f \"tokens=5\" %a in (\\'netstat -ano ^| findstr :8080\\') do taskkill /F /PID %a', { stdio: 'inherit' });\n } else {\n // For Unix platforms, find and kill the tappd-simulator process\n execSync('pkill -f tappd-simulator', { stdio: 'inherit' });\n }\n \n // Verify the simulator has stopped\n const stopped = !(await isSimulatorRunning());\n if (stopped) {\n logger.success('Simulator stopped successfully');\n } else {\n logger.error('Failed to stop simulator');\n }\n \n await deleteSimulatorEndpointEnv();\n return stopped;\n } catch (error) {\n logger.error('Error stopping simulator:', error);\n return false;\n }\n}\n\n/**\n * Gets the path to the simulator log file\n * @param customPath Optional custom log file path\n * @returns The path to the log file\n */\nexport function getSimulatorLogPath(customPath?: string): string {\n return customPath ?? SIMULATOR_CONFIG.defaultLogPath;\n}\n\n/**\n * Reads the recent logs from the simulator log file\n * @param options Options for reading logs\n * @returns Recent log content or null if log file doesn't exist\n */\nexport function getSimulatorLogs(options: {\n logFilePath?: string;\n maxLines?: number;\n} = {}): string | null {\n const logFilePath = options.logFilePath ?? SIMULATOR_CONFIG.defaultLogPath;\n const maxLines = options.maxLines ?? 100;\n \n try {\n if (!fs.existsSync(logFilePath)) {\n return null;\n }\n \n // Read the log file\n const logContent = fs.readFileSync(logFilePath, 'utf8');\n \n // Split by lines and get the most recent ones\n const lines = logContent.split('\\n');\n return lines.slice(-maxLines).join('\\n');\n } catch (error) {\n logger.error('Error reading simulator logs:', error);\n return null;\n }\n}\n\n/**\n * Gets the simulator endpoint URL based on the current platform\n * @returns The endpoint URL for the simulator\n */\nexport function getSimulatorEndpoint(): string {\n const platform = getPlatform();\n \n if (platform === 'win32') {\n return 'http://127.0.0.1:8090';\n }\n\n return 'unix:///tmp/tappd.sock';\n}\n\n/**\n * Sets the DSTACK_SIMULATOR_ENDPOINT environment variable based on the current platform\n * @param options Configuration options for setting the environment variable\n * @returns The endpoint URL that was set\n */\nexport async function setSimulatorEndpointEnv(endpoint?: string): Promise<string> {\n try {\n const simulatorEndpoint = getSimulatorEndpoint();\n // Set for the current Node.js process\n const envEndpoint = (endpoint) ? endpoint : simulatorEndpoint;\n await execSync(`export DSTACK_SIMULATOR_ENDPOINT=${envEndpoint}`);\n logger.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${envEndpoint} for current process`);\n \n return endpoint;\n } catch (error) {\n logger.error('Error setting simulator endpoint environment variable:', error);\n throw new Error(`Failed to set simulator endpoint: ${error}`);\n }\n}\n\n/**\n * Deletes the DSTACK_SIMULATOR_ENDPOINT environment variable\n * @returns boolean indicating if deletion was successful\n */\nexport async function deleteSimulatorEndpointEnv(): Promise<boolean> {\n await execSync('unset DSTACK_SIMULATOR_ENDPOIN');\n logger.success('Deleted DSTACK_SIMULATOR_ENDPOINT from current process');\n return true;\n}\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport path from 'node:path';\nimport inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport { promptForFile } from '@/src/utils/prompts';\n\nexport const buildCommand = new Command()\n .name('build')\n .description('Build a Docker image')\n .option('-i, --image <image>', 'Image name')\n .option('-t, --tag <tag>', 'Image tag')\n .option('-f, --file <file>', 'Path to Dockerfile', 'Dockerfile')\n .action(async (options) => {\n try {\n // Get Docker credentials\n const credentials = await getDockerCredentials();\n \n if (!credentials) {\n logger.error('Docker information not found. Please login first with \"phala docker login\"');\n process.exit(1);\n }\n \n // Prompt for image name if not provided\n if (!options.image) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'image',\n message: 'Enter the Docker image name:',\n validate: (input) => {\n if (!input.trim()) {\n return 'Image name is required';\n }\n return true;\n }\n }\n ]);\n \n options.image = response.image;\n }\n\n if (!options.tag) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'tag',\n message: 'Enter the Docker image tag:',\n default: 'latest', // Add random hash later\n validate: (input) => {\n if (!input.trim()) {\n return 'Tag is required';\n }\n return true;\n }\n }\n ]);\n\n options.tag = response.tag;\n }\n\n // Prompt for Dockerfile path if the default doesn't exist\n const defaultPath = path.resolve(process.cwd(), options.file);\n if (!fs.existsSync(defaultPath)) {\n logger.info(`Default Dockerfile not found at ${defaultPath}`);\n \n options.file = await promptForFile(\n 'Enter the path to your Dockerfile:',\n 'Dockerfile',\n 'file'\n );\n }\n \n // Resolve the Dockerfile path\n const dockerfilePath = path.resolve(process.cwd(), options.file);\n \n // Build the image\n const dockerService = new DockerService(options.image, credentials.username, credentials.registry);\n const success = await dockerService.buildImage(dockerfilePath, options.tag);\n \n if (!success) {\n logger.error('Failed to build Docker image');\n process.exit(1);\n }\n \n logger.success(`Docker image ${credentials.username}/${options.image}:${options.tag} built successfully`);\n } catch (error) {\n logger.error(`Failed to build Docker image: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\n\nexport const pushCommand = new Command()\n .name('push')\n .description('Push a Docker image to Docker Hub')\n .option('-i, --image <image>', 'Full image name (e.g. username/image:tag)')\n .action(async (options) => {\n try {\n // Get Docker credentials\n const credentials = await getDockerCredentials();\n \n if (!credentials) {\n logger.error('Docker information not found. Please login first with \"phala docker login\"');\n process.exit(1);\n }\n\n let imageName = options.image;\n\n // If image name is not provided, list local images and prompt user to select\n if (!imageName) {\n const localImages = await DockerService.listLocalImages();\n \n if (localImages.length === 0) {\n logger.error('No local Docker images found. Please build an image first with \"phala docker build\"');\n process.exit(1);\n }\n\n // If no image specified, prompt to select from available images\n if (!imageName) {\n // Get unique image names\n const uniqueImageNames = Array.from(new Set(localImages.map(img => img.imageName)));\n \n const { selectedImage } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedImage',\n message: 'Select an image to push:',\n choices: uniqueImageNames\n }\n ]);\n \n imageName = selectedImage;\n }\n }\n \n // Push the image\n const dockerService = new DockerService('', credentials.username, credentials.registry);\n const success = await dockerService.pushImage(imageName);\n \n if (!success) {\n logger.error('Failed to push Docker image');\n process.exit(1);\n }\n \n logger.success(`Docker image ${imageName} pushed successfully`);\n } catch (error) {\n logger.error(`Failed to push Docker image: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { validateFileExists } from '@/src/utils/prompts';\n\nexport const generateCommand = new Command()\n .name('generate')\n .description('Generate a Docker Compose file')\n .option('-i, --image <imageName>', 'Docker image name to use in the compose file (e.g. phala/phala-cloud)')\n .option('-e, --env-file <envFile>', 'Path to environment variables file')\n .option('-o, --output <output>', 'Output path for generated docker-compose.yml')\n .option('--template <template>', 'Template to use for the generated docker-compose.yml', )\n .action(async (options) => {\n try {\n // Get Docker credentials to create the Docker service\n const credentials = await getDockerCredentials();\n if (!credentials || !credentials.username) {\n logger.error('Docker Hub username not found. Please login first with `phala docker login`');\n process.exit(1);\n }\n\n let imageName = options.image;\n\n if (!imageName) {\n // If image name is not provided, list local images and prompt user to select\n const localImages = await DockerService.listLocalImages();\n\n if (localImages.length === 0) {\n logger.error(\n 'No local Docker images found. Please build an image first with \"phala docker build\"',\n );\n process.exit(1);\n }\n\n // If no image specified, prompt to select from available images\n if (!imageName) {\n // Get unique image names\n const uniqueImageNames = Array.from(\n new Set(localImages.map((img) => img.imageName)),\n );\n\n const { selectedImage } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selectedImage\",\n message: \"Select an image to use in the compose file:\",\n choices: uniqueImageNames,\n },\n ]);\n\n imageName = selectedImage;\n }\n }\n \n // Get environment file path from options or prompt\n let envFilePath = options.envFile;\n if (!envFilePath) {\n // Check if .env exists in current directory\n const defaultEnvPath = path.join(process.cwd(), '.env');\n const hasDefaultEnv = fs.existsSync(defaultEnvPath);\n\n if (hasDefaultEnv) {\n const { useDefault } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'useDefault',\n message: 'Use .env file in current directory?',\n default: true\n }\n ]);\n\n if (useDefault) {\n envFilePath = defaultEnvPath;\n }\n }\n\n // If still no env file path, prompt for it\n if (!envFilePath) {\n const { envPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'envPath',\n message: 'Enter path to environment variables file:',\n validate: (input) => {\n try {\n validateFileExists(input);\n return true;\n } catch (error) {\n return `File not found: ${input}`;\n }\n }\n }\n ]);\n envFilePath = envPath;\n }\n } else {\n // Validate the provided env file path\n try {\n validateFileExists(envFilePath);\n } catch (error) {\n logger.error(`File not found: ${envFilePath}`);\n process.exit(1);\n }\n }\n\n // Get output path from options or set default\n let outputPath = options.output;\n if (!outputPath) {\n outputPath = path.join(process.cwd(), 'docker-compose.yml');\n \n // If file already exists, confirm overwrite\n if (fs.existsSync(outputPath)) {\n const { confirmOverwrite } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmOverwrite',\n message: `File ${outputPath} already exists. Overwrite?`,\n default: false\n }\n ]);\n if (!confirmOverwrite) {\n const { customPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'customPath',\n message: 'Enter alternative output path:',\n default: path.join(process.cwd(), 'docker-generated-compose.yml')\n }\n ]);\n outputPath = customPath;\n }\n }\n }\n \n // Create a DockerService instance\n const dockerService = new DockerService('', credentials.username, credentials.registry);\n\n // Generate the Docker Compose file\n if (envFilePath) {\n logger.info(`Generating Docker Compose file for ${imageName} using env file: ${envFilePath}`);\n } else {\n logger.info(`Generating Docker Compose file for ${imageName} without env file`);\n }\n const composePath = await dockerService.buildComposeFile(imageName, envFilePath, options.template);\n \n // Copy the generated file to the output path if needed\n if (composePath !== outputPath) {\n // Ensure the output directory exists\n const outputDir = path.dirname(outputPath);\n if (!fs.existsSync(outputDir)) {\n logger.info(`Creating directory: ${outputDir}`);\n fs.mkdirSync(outputDir, { recursive: true });\n }\n \n fs.copyFileSync(composePath, outputPath);\n }\n \n logger.success(`Docker Compose file generated successfully: ${outputPath}`);\n } catch (error) {\n logger.error(`Failed to generate Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { startCommand } from './start';\nimport { stopCommand } from './stop';\n\nexport const simulatorCommands = new Command()\n .name('simulator')\n .description('TEE simulator commands')\n .addCommand(startCommand)\n .addCommand(stopCommand);\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { logger } from '@/src/utils/logger';\nimport { TEE_SIMULATOR } from '@/src/utils/constants';\nimport { installSimulator, isSimulatorInstalled, isSimulatorRunning, runSimulator } from '@/src/utils/simulator';\n\nexport const startCommand = new Command()\n .name('start')\n .description('Start the TEE simulator')\n .option('-i, --image <image>', 'Simulator image', TEE_SIMULATOR)\n .option('-p, --port <port>', 'Simulator port (default: 8090)', '8090')\n .option('-t, --type <type>', 'Simulator type (docker, native)', 'docker')\n .action(async (options) => {\n try {\n if (options.type === 'docker') {\n // Start the simulator\n const dockerService = new DockerService('');\n const success = await dockerService.runSimulator(options.image, options.port);\n \n if (!success) {\n logger.error('Failed to start TEE simulator');\n process.exit(1);\n }\n } else if (options.type === 'native') {\n if (!isSimulatorInstalled()) {\n await installSimulator();\n }\n const running = await isSimulatorRunning();\n if (running) {\n logger.success('TEE simulator is already running');\n return;\n } else {\n const simulatorProcess = runSimulator();\n logger.success('TEE simulator started successfully');\n }\n } else {\n logger.error('Invalid simulator type');\n process.exit(1);\n }\n } catch (error) {\n logger.error(`Failed to start TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '../../utils/docker';\nimport { logger } from '../../utils/logger';\nimport { stopSimulator } from '@/src/utils/simulator';\n\nexport const stopCommand = new Command()\n .name('stop')\n .description('Stop the TEE simulator')\n .option('-t, --type <type>', 'Simulator type (docker, native)', 'docker')\n .action(async (options) => {\n try {\n if (options.type === 'docker') {\n // Stop the simulator\n const dockerService = new DockerService('');\n const success = await dockerService.stopSimulator();\n\n if (!success) {\n logger.error('Failed to stop TEE simulator');\n process.exit(1);\n }\n } else if (options.type === 'native') {\n // Stop the native simulator\n const success = await stopSimulator();\n \n if (!success) {\n logger.error('Failed to stop TEE simulator');\n process.exit(1);\n }\n } else {\n logger.error('Invalid simulator type');\n process.exit(1);\n }\n } catch (error) {\n logger.error(`Failed to stop TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });","import { Command } from 'commander';\nimport { listCommand } from './list';\nimport { getCommand } from './get';\nimport { startCommand } from './start';\nimport { stopCommand } from './stop';\nimport { restartCommand } from './restart';\nimport { attestationCommand } from './attestation';\nimport { createCommand } from './create';\nimport { deleteCommand } from './delete';\nimport { upgradeCommand } from './upgrade';\nimport { resizeCommand } from './resize';\n\nexport const cvmsCommand = new Command()\n .name('cvms')\n .description('Manage Phala Confidential Virtual Machines (CVMs)')\n .addCommand(attestationCommand)\n .addCommand(createCommand)\n .addCommand(deleteCommand)\n .addCommand(getCommand)\n .addCommand(listCommand)\n .addCommand(startCommand)\n .addCommand(stopCommand)\n .addCommand(resizeCommand)\n .addCommand(restartCommand)\n .addCommand(upgradeCommand);\n ","import { Command } from 'commander';\nimport { getCvms } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { CLOUD_URL } from '@/src/utils/constants';\nimport chalk from 'chalk';\n\nexport const listCommand = new Command()\n .name('list')\n .alias('ls')\n .description('List all CVMs')\n .option('-j, --json', 'Output in JSON format')\n .action(async (options) => {\n try {\n const spinner = logger.startSpinner('Fetching CVMs');\n \n const cvms = await getCvms();\n \n spinner.stop(true);\n \n if (!cvms || cvms.length === 0) {\n logger.info('No CVMs found');\n return;\n }\n \n if (options.json) {\n console.log(JSON.stringify(cvms, null, 2));\n return;\n }\n \n for (const cvm of cvms) {\n logger.keyValueTable({\n Name: cvm.name,\n \"App ID\": `app_${cvm.hosted.app_id}`,\n Status:\n cvm.status === \"running\"\n ? chalk.green(cvm.status)\n : cvm.status === \"stopped\"\n ? chalk.red(cvm.status)\n : chalk.yellow(cvm.status),\n \"Node Info URL\": cvm.hosted.app_url,\n \"App URL\": `${CLOUD_URL}/dashboard/cvms/app_${cvm.hosted.app_id}`,\n });\n logger.break();\n }\n logger.success(`Found ${cvms.length} CVMs`);\n logger.break();\n logger.info(`Go to ${CLOUD_URL}/dashboard/ to view your CVMs`);\n } catch (error) {\n logger.error(`Failed to list CVMs: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '@/src/utils/constants';\nimport { logger } from '@/src/utils/logger';\nimport {\n cvmInstanceSchema,\n getCvmByAppIdResponseSchema,\n getPubkeyFromCvmResponseSchema,\n postCvmResponseSchema,\n upgradeCvmResponseSchema,\n cvmAttestationResponseSchema,\n getCvmNetworkResponseSchema,\n} from './types';\nimport type {\n CvmInstance,\n GetCvmByAppIdResponse,\n GetPubkeyFromCvmResponse,\n PostCvmResponse,\n UpgradeCvmResponse,\n CvmAttestationResponse,\n GetCvmNetworkResponse,\n} from './types';\nimport inquirer from 'inquirer';\nimport { z } from 'zod';\n\n/**\n * Get all CVMs for the current user\n * @returns List of CVMs\n */\nexport async function getCvms(): Promise<CvmInstance[]> {\n try {\n const response = await apiClient.get<CvmInstance[]>(API_ENDPOINTS.CVMS(0));\n return z.array(cvmInstanceSchema).parse(response);\n } catch (error) {\n throw new Error(`Failed to get CVMs: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * VM configuration type\n */\nexport interface VMConfig {\n // Add specific properties as needed\n [key: string]: unknown;\n}\n\n/**\n * Update payload type\n */\nexport interface UpdateCvmPayload {\n app_id: string;\n [key: string]: unknown;\n}\n\n/**\n * Check CVM exists for the current user and appId\n * @param appId App ID\n * @returns CVM appId string or null if it doesn't exist\n */\nexport async function checkCvmExists(appId: string): Promise<string> {\n const cvms = await getCvms();\n const cvm = cvms.find(cvm => (cvm.hosted?.app_id === appId || `app_${cvm.hosted?.app_id}` === appId));\n if (!cvm) {\n logger.error(`CVM with App ID app_${appId} not detected`);\n process.exit(1);\n } else {\n logger.success(`CVM with App ID app_${appId} detected`);\n return cvm.hosted?.app_id || '';\n }\n}\n\n/**\n * Get a CVM by App ID\n * @param appId App ID\n * @returns CVM details\n */\nexport async function getCvmByAppId(appId: string): Promise<GetCvmByAppIdResponse> {\n try {\n const response = await apiClient.get<GetCvmByAppIdResponse>(API_ENDPOINTS.CVM_BY_APP_ID(appId));\n return getCvmByAppIdResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get CVM by App ID: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get public key from CVM\n * @param vmConfig VM configuration\n * @returns Public key\n */\nexport async function getPubkeyFromCvm(vmConfig: VMConfig): Promise<GetPubkeyFromCvmResponse> {\n try {\n const response = await apiClient.post<GetPubkeyFromCvmResponse>(API_ENDPOINTS.CVM_PUBKEY, vmConfig);\n return getPubkeyFromCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get pubkey from CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get network information for a CVM\n * @param appId App ID\n * @returns Network information\n */\nexport async function getCvmNetwork(appId: string): Promise<GetCvmNetworkResponse> {\n try {\n const response = await apiClient.get<GetCvmNetworkResponse>(API_ENDPOINTS.CVM_NETWORK(appId));\n return getCvmNetworkResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get network information for CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Create a new CVM\n * @param vmConfig VM configuration\n * @returns Created CVM details\n */\nexport async function createCvm(vmConfig: VMConfig): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_FROM_CONFIGURATION, vmConfig);\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n if (error instanceof z.ZodError) {\n logger.error('Schema validation error:', JSON.stringify(error.errors, null, 2));\n logger.error('API response:', JSON.stringify(error.format(), null, 2));\n throw new Error(`Response validation failed: ${JSON.stringify(error.errors)}`);\n }\n throw new Error(`Failed to create CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Start a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function startCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_START(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to start CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Stop a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function stopCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_STOP(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to stop CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Restart a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function restartCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_RESTART(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to restart CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Upgrade a CVM\n * @param appId App ID\n * @param vmConfig VM configuration\n * @returns Upgrade response\n */\nexport async function upgradeCvm(appId: string, vmConfig: VMConfig): Promise<UpgradeCvmResponse> {\n try {\n const response = await apiClient.put<UpgradeCvmResponse>(API_ENDPOINTS.CVM_UPGRADE(appId), vmConfig);\n return upgradeCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Delete a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function deleteCvm(appId: string): Promise<boolean> {\n try {\n await apiClient.delete(API_ENDPOINTS.CVM_BY_APP_ID(appId));\n return true;\n } catch (error) {\n throw new Error(`Failed to delete CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Update a CVM\n * @param updatePayload Update payload\n * @returns Updated CVM details\n */\nexport async function updateCvm(updatePayload: UpdateCvmPayload): Promise<unknown> {\n try {\n const response = await apiClient.put(API_ENDPOINTS.CVM_BY_APP_ID(updatePayload.app_id), updatePayload);\n return response;\n } catch (error) {\n throw new Error(`Failed to update CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Presents a list of CVMs to the user and allows them to select one\n * @returns The selected CVM app ID or undefined if no CVMs exist\n */\nexport async function selectCvm(): Promise<string | undefined> {\n const listSpinner = logger.startSpinner('Fetching available CVMs');\n const cvms = await getCvms();\n listSpinner.stop(true);\n \n if (!cvms || cvms.length === 0) {\n logger.info('No CVMs found for your account');\n return undefined;\n }\n \n // Prepare choices for the inquirer prompt\n const choices = cvms.map(cvm => {\n // Handle different API response formats\n const id = cvm.hosted?.app_id || cvm.hosted?.id;\n const name = cvm.name || cvm.hosted?.name;\n const status = cvm.status || cvm.hosted?.status;\n \n return {\n name: `${name || 'Unnamed'} (${id}) - Status: ${status || 'Unknown'}`,\n value: id\n };\n });\n \n const { selectedCvm } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedCvm',\n message: 'Select a CVM:',\n choices\n }\n ]);\n \n return selectedCvm;\n}\n\n/**\n * Get attestation information for a CVM\n * @param appId App ID\n * @returns Attestation information\n */\nexport async function getCvmAttestation(appId: string): Promise<CvmAttestationResponse> {\n try {\n const response = await apiClient.get<CvmAttestationResponse>(API_ENDPOINTS.CVM_ATTESTATION(appId));\n \n // Attempt to validate and return the response\n try {\n return cvmAttestationResponseSchema.parse(response);\n } catch (validationError) {\n logger.debug(`Validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`);\n \n // If validation fails, create a normalized response object\n const normalizedResponse: CvmAttestationResponse = {\n is_online: Boolean(response?.is_online),\n is_public: Boolean(response?.is_public),\n error: typeof response?.error === 'string' ? response.error : null,\n app_certificates: Array.isArray(response?.app_certificates) ? response.app_certificates : null,\n tcb_info: response?.tcb_info || null,\n compose_file: typeof response?.compose_file === 'string' ? response.compose_file : null\n };\n \n return normalizedResponse;\n }\n } catch (error) {\n throw new Error(`Failed to get attestation information: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Resize payload type\n */\nexport interface ResizeCvmPayload {\n vcpu?: number;\n memory?: number;\n disk_size?: number;\n allow_restart?: number;\n}\n\n/**\n * Resize a CVM's resources\n * @param appId App ID\n * @param vcpu Number of virtual CPUs (optional)\n * @param memory Memory size in MB (optional)\n * @param diskSize Disk size in GB (optional)\n * @param allowRestart Whether to allow restart (1) or not (0) for the resize operation (optional)\n * @returns Success status\n */\nexport async function resizeCvm(\n appId: string, \n vcpu?: number, \n memory?: number, \n diskSize?: number, \n allowRestart?: number\n): Promise<boolean> {\n try {\n // Only include defined parameters in the payload\n const resizePayload: ResizeCvmPayload = {};\n \n if (vcpu !== undefined) resizePayload.vcpu = vcpu;\n if (memory !== undefined) resizePayload.memory = memory;\n if (diskSize !== undefined) resizePayload.disk_size = diskSize;\n if (allowRestart !== undefined) resizePayload.allow_restart = allowRestart;\n \n // Check if any parameters were provided\n if (Object.keys(resizePayload).length === 0) {\n throw new Error('At least one resource parameter must be provided');\n }\n \n await apiClient.patch(API_ENDPOINTS.CVM_RESIZE(appId), resizePayload);\n return true;\n } catch (error) {\n throw new Error(`Failed to resize CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n} ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmByAppId, getCvms, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { CLOUD_URL } from '@/src/utils/constants';\nimport chalk from 'chalk';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\n\nexport const getCommand = new Command()\n .name('get')\n .description('Get details of a CVM')\n .argument('[app-id]', 'App ID of the CVM (optional)')\n .option('-j, --json', 'Output in JSON format')\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n const spinner = logger.startSpinner(`Fetching CVM with App ID app_${resolvedAppId}`);\n \n const cvm = await getCvmByAppId(resolvedAppId);\n \n spinner.stop(true);\n logger.break();\n \n if (!cvm) {\n logger.error(`CVM with App ID app_${resolvedAppId} not found`);\n process.exit(1);\n }\n \n if (options.json) {\n console.log(JSON.stringify(cvm, null, 2));\n return;\n }\n \n // Display additional details if available\n logger.keyValueTable({\n 'Name': cvm.name,\n 'App ID': `app_${cvm.app_id}`,\n 'Status': (cvm.status === 'running') ? chalk.green(cvm.status) : (cvm.status === 'stopped') ? chalk.red(cvm.status) : chalk.yellow(cvm.status),\n 'vCPU': cvm.vcpu,\n 'Memory': `${cvm.memory} MB`,\n 'Disk Size': `${cvm.disk_size} GB`,\n 'Dstack Image': cvm.base_image,\n 'App URL': `${CLOUD_URL}/dashboard/cvms/app_${cvm.app_id}`\n });\n } catch (error) {\n logger.error(`Failed to get CVM details: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { selectCvm, checkCvmExists } from \"@/src/api/cvms\";\nimport { logger } from \"./logger\";\n\n/**\n * Resolves a CVM App ID either by prompting the user to select one if none is provided,\n * or by validating the provided App ID exists.\n *\n * @param appId Optional App ID to resolve\n * @returns The resolved App ID or undefined if none was selected/found\n */\nexport async function resolveCvmAppId(\n\tappId?: string,\n): Promise<string | undefined> {\n\tif (!appId) {\n\t\t// If no app ID is provided, prompt user to select one\n\t\tconst selectedCvm = await selectCvm();\n\t\tif (!selectedCvm) {\n\t\t\treturn undefined; // No CVMs found or user canceled\n\t\t}\n\t\treturn selectedCvm;\n\t}\n\t// Verify the provided App ID exists\n\treturn await checkCvmExists(appId);\n}","import { Command } from 'commander';\nimport { startCvm, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const startCommand = new Command()\n .name('start')\n .description('Start a stopped CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n const spinner = logger.startSpinner(`Starting CVM with App ID app_${resolvedAppId}`);\n \n const response = await startCvm(resolvedAppId);\n \n spinner.stop(true);\n logger.break();\n \n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n \n logger.break();\n logger.success(\n `Your CVM is being started. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to start CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { stopCvm, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const stopCommand = new Command()\n .name('stop')\n .description('Stop a running CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const spinner = logger.startSpinner(\n `Stopping CVM with App ID app_${resolvedAppId}`,\n );\n\n const response = await stopCvm(resolvedAppId);\n\n spinner.stop(true);\n logger.break();\n\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n\n logger.break();\n logger.success(\n `Your CVM is being stopped. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n \n } catch (error) {\n logger.error(`Failed to stop CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, restartCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const restartCommand = new Command()\n .name('restart')\n .description('Restart a CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const spinner = logger.startSpinner(\n `Restarting CVM with App ID app_${resolvedAppId}`,\n );\n\n const response = await restartCvm(resolvedAppId);\n\n spinner.stop(true);\n logger.break();\n\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n 'App URL': response.app_url\n ? response.app_url\n : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: \"rounded\",\n });\n\n logger.break();\n logger.success(\n `Your CVM is being restarted. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to restart CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmAttestation, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport chalk from 'chalk';\nimport type { CvmAttestationResponse } from '@/src/api/types';\n\nexport const attestationCommand = new Command()\n .name('attestation')\n .description('Get attestation information for a CVM')\n .argument('[app-id]', 'CVM app ID (will prompt for selection if not provided)')\n .option('-j, --json', 'Output in JSON format')\n .action(async (appId?: string, options?: { json?: boolean }) => {\n try {\n let resolvedAppId: string;\n \n if (!appId) {\n logger.info('No CVM specified, fetching available CVMs...');\n const selectedCvm = await selectCvm();\n if (!selectedCvm) {\n return;\n }\n resolvedAppId = selectedCvm;\n } else {\n resolvedAppId = await checkCvmExists(appId);\n }\n\n const spinner = logger.startSpinner(`Fetching attestation information for CVM app_${resolvedAppId}...`);\n\n try {\n const attestationData: CvmAttestationResponse = await getCvmAttestation(resolvedAppId);\n spinner.stop(true);\n\n if (!attestationData || Object.keys(attestationData).length === 0) {\n logger.info('No attestation information found');\n return;\n }\n\n // If JSON output is requested, just print the raw response\n if (options?.json) {\n logger.info(JSON.stringify(attestationData, null, 2));\n return;\n }\n\n // Display the attestation summary\n logger.success('Attestation Summary:');\n const summaryData = {\n 'Status': attestationData.is_online ? chalk.green('Online') : chalk.red('Offline'),\n 'Public Access': attestationData.is_public ? chalk.green('Enabled') : chalk.yellow('Disabled'),\n 'Error': attestationData.error || 'None',\n 'Certificates': `${attestationData.app_certificates?.length || 0} found`\n };\n \n logger.keyValueTable(summaryData, {\n borderStyle: 'rounded'\n });\n\n // Display certificate information\n if (attestationData.app_certificates && attestationData.app_certificates.length > 0) {\n \n attestationData.app_certificates.forEach((cert, index) => {\n logger.break();\n logger.success(`Certificate #${index + 1} (${cert.position_in_chain === 0 ? 'End Entity' : 'CA'}):`);\n \n const certData = {\n 'Subject': `${cert.subject.common_name || 'Unknown'}${cert.subject.organization ? ` (${cert.subject.organization})` : ''}`,\n 'Issuer': `${cert.issuer.common_name || 'Unknown'}${cert.issuer.organization ? ` (${cert.issuer.organization})` : ''}`,\n 'Serial Number': cert.serial_number,\n 'Validity': `${new Date(cert.not_before).toLocaleString()} to ${new Date(cert.not_after).toLocaleString()}`,\n 'Fingerprint': cert.fingerprint,\n 'Signature Algorithm': cert.signature_algorithm,\n 'Is CA': cert.is_ca ? 'Yes' : 'No',\n 'Position in Chain': cert.position_in_chain\n };\n \n logger.keyValueTable(certData, {\n borderStyle: 'rounded'\n });\n \n // Skip displaying the quote as it's very large and mostly binary data\n });\n }\n\n // Display TCB info if available\n if (attestationData.tcb_info) {\n logger.break();\n logger.success('Trusted Computing Base (TCB) Information:');\n \n // Create a formatted version of the TCB info without the event log\n const tcbBasicInfo = {\n 'Mrtd': attestationData.tcb_info.mrtd,\n 'Rootfs Hash': attestationData.tcb_info.rootfs_hash,\n 'Rtmr0': attestationData.tcb_info.rtmr0,\n 'Rtmr1': attestationData.tcb_info.rtmr1,\n 'Rtmr2': attestationData.tcb_info.rtmr2,\n 'Rtmr3': attestationData.tcb_info.rtmr3,\n 'Event Log Entries': `${attestationData.tcb_info.event_log.length} entries`\n };\n \n // Display basic TCB info\n logger.keyValueTable(tcbBasicInfo, {\n borderStyle: 'rounded'\n });\n \n // Display event log entries separately if they exist\n if (attestationData.tcb_info.event_log && attestationData.tcb_info.event_log.length > 0) {\n logger.break();\n logger.success('Event Log (Showing entries to reproduce RTMR3):');\n \n // Show the first 5 entries\n const maxEntriesToShow = 5;\n const entries = attestationData.tcb_info.event_log\n .filter(entry => entry.event !== null && entry.event !== \"\")\n .map((entry) => ({\n 'Event': entry.event,\n 'IMR': entry.imr.toString(),\n 'Event Type': entry.event_type.toString(),\n 'Payload': entry.event_payload,\n }));\n \n // Display entries in a table format\n logger.table(entries, [\n { key: \"Event\", header: \"Event\", minWidth: 8 },\n { key: \"IMR\", header: \"IMR\", minWidth: 3 },\n { key: \"Event Type\", header: \"Type\", minWidth: 8 },\n { key: \"Payload\", header: \"Payload\", minWidth: 25 },\n ]);\n \n if (attestationData.tcb_info.event_log.length > maxEntriesToShow) {\n logger.info('To see all full attestation data, use --json');\n }\n logger.break();\n logger.success('To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/');\n }\n }\n } catch (error) {\n spinner.stop(false);\n throw error;\n }\n } catch (error) {\n logger.error(`Failed to get attestation information: ${error instanceof Error ? error.message : String(error)}`);\n }\n });\n","import { Command } from 'commander';\nimport { createCvm, getPubkeyFromCvm } from '@/src/api/cvms';\nimport { getTeepods } from '@/src/api/teepods';\nimport { logger } from '@/src/utils/logger';\nimport type { TEEPod, Image } from '@/src/api/types';\nimport { DEFAULT_VCPU, DEFAULT_MEMORY, DEFAULT_DISK_SIZE, CLOUD_URL } from '@/src/utils/constants';\nimport { encryptEnvVars, type EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport inquirer from 'inquirer';\nimport { parseEnv } from '@/src/utils/secrets';\nimport { detectFileInCurrentDir, promptForFile } from '@/src/utils/prompts';\nimport { deleteSimulatorEndpointEnv } from '@/src/utils/simulator';\n\nexport const createCommand = new Command()\n .name('create')\n .description('Create a new CVM')\n .option('-n, --name <name>', 'Name of the CVM')\n .option('-c, --compose <compose>', 'Path to Docker Compose file')\n .option('--vcpu <vcpu>', `Number of vCPUs, default is ${DEFAULT_VCPU}`)\n .option('--memory <memory>', `Memory in MB, default is ${DEFAULT_MEMORY}`)\n .option('--disk-size <diskSize>', `Disk size in GB, default is ${DEFAULT_DISK_SIZE}`)\n .option('--teepod-id <teepodId>', 'TEEPod ID to use. If not provided, it will be selected from the list of available TEEPods.')\n .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.')\n .option('-e, --env-file <envFile>', 'Path to environment file')\n .option('--skip-env', 'Skip environment variable prompt', false)\n .option('--debug', 'Enable debug mode', false)\n .action(async (options) => {\n try {\n // Prompt for required options if not provided\n if (!options.name) {\n const { name } = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Enter a name for the CVM:',\n validate: (input) => {\n if (!input.trim()) {\n return 'CVM name is required';\n }\n if (input.trim().length > 20) {\n return 'CVM name must be less than 20 characters';\n } else if (input.trim().length < 3) {\n return 'CVM name must be at least 3 characters';\n } else if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return 'CVM name must contain only letters, numbers, underscores, and hyphens';\n }\n return true;\n }\n }\n ]);\n options.name = name;\n }\n\n // If compose path not provided, prompt with examples\n if (!options.compose) {\n const possibleFiles = ['docker-compose.yml', 'docker-compose.yaml'];\n const composeFileName = detectFileInCurrentDir(possibleFiles, 'Detected docker compose file: {path}');\n\n options.compose = await promptForFile(\n 'Enter the path to your Docker Compose file:',\n composeFileName,\n 'file'\n );\n }\n\n const composePath = path.resolve(options.compose);\n if (!fs.existsSync(composePath)) {\n logger.error(`Docker Compose file not found: ${composePath}`);\n process.exit(1);\n }\n const composeString = fs.readFileSync(composePath, 'utf8');\n\n // Delete DSTACK_SIMULATOR_ENDPOINT environment variable\n await deleteSimulatorEndpointEnv();\n\n // Process environment variables\n let envs: EnvVar[] = [];\n\n // Process environment variables from file\n if (options.envFile) {\n try {\n envs = parseEnv([], options.envFile);\n } catch (error) {\n logger.error(`Failed to read environment file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n } else if (!options.skipEnv) {\n // Prompt to input env file or skip\n const { shouldSkip } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldSkip',\n message: 'Do you want to skip environment variable prompt?',\n default: true\n }\n ]);\n \n if (shouldSkip) {\n logger.info('Skipping environment variable prompt');\n } else {\n const envVars = await promptForFile(\n 'Enter the path to your environment file:',\n '.env',\n 'file',\n );\n envs = parseEnv([], envVars);\n }\n }\n\n const vcpu = Number(options.vcpu) || DEFAULT_VCPU;\n const memory = Number(options.memory) || DEFAULT_MEMORY;\n const diskSize = Number(options.diskSize) || DEFAULT_DISK_SIZE;\n\n if (isNaN(vcpu) || vcpu <= 0) {\n logger.error(`Invalid number of vCPUs: ${vcpu}`);\n process.exit(1);\n }\n\n if (isNaN(memory) || memory <= 0) {\n logger.error(`Invalid memory: ${memory}`);\n process.exit(1);\n }\n\n if (isNaN(diskSize) || diskSize <= 0) {\n logger.error(`Invalid disk size: ${diskSize}`);\n process.exit(1);\n }\n\n const teepodsSpinner = logger.startSpinner('Fetching available TEEPods');\n const teepods = await getTeepods();\n teepodsSpinner.stop(true);\n if (teepods.length === 0) {\n logger.error('No TEEPods available. Please try again later.');\n process.exit(1);\n }\n\n let selectedTeepod: TEEPod;\n // Fetch available TEEPods\n if (!options.teepodId) {\n selectedTeepod = teepods[0];\n } else {\n selectedTeepod = teepods.find(pod => pod.teepod_id === options.teepodId);\n if (!selectedTeepod) {\n logger.error('Failed to find selected TEEPod');\n process.exit(1);\n }\n }\n\n let selectedImage: Image;\n if (!options.image) {\n selectedImage = selectedTeepod.images![0];\n } else {\n const selectedImage = selectedTeepod.images?.find(image => image.name === options.image);\n if (!selectedImage) {\n logger.error(`Failed to find selected image: ${options.image}`);\n process.exit(1);\n }\n }\n\n // Prepare VM configuration\n const vmConfig = {\n teepod_id: selectedTeepod.teepod_id,\n name: options.name,\n image: selectedImage.name,\n vcpu: vcpu,\n memory: memory,\n disk_size: diskSize,\n compose_manifest: {\n docker_compose_file: composeString,\n docker_config: {\n url: '',\n username: '',\n password: '',\n },\n features: ['kms', 'tproxy-net'],\n kms_enabled: true,\n manifest_version: 2,\n name: options.name,\n public_logs: true,\n public_sysinfo: true,\n tproxy_enabled: true,\n },\n listed: false,\n };\n\n // Get public key from CVM\n const spinner = logger.startSpinner('Getting public key from CVM');\n const pubkey = await getPubkeyFromCvm(vmConfig);\n spinner.stop(true);\n\n if (!pubkey) {\n logger.error('Failed to get public key from CVM');\n process.exit(1);\n }\n\n // Encrypt environment variables\n const encryptSpinner = logger.startSpinner('Encrypting environment variables');\n const encrypted_env = await encryptEnvVars(envs, pubkey.app_env_encrypt_pubkey);\n encryptSpinner.stop(true);\n\n if (options.debug) {\n logger.debug('Public key:', pubkey.app_env_encrypt_pubkey);\n logger.debug('Encrypted environment variables:', encrypted_env);\n logger.debug('Environment variables:', JSON.stringify(envs));\n }\n\n // Create the CVM\n const createSpinner = logger.startSpinner('Creating CVM');\n const response = await createCvm({\n ...vmConfig,\n encrypted_env,\n app_env_encrypt_pubkey: pubkey.app_env_encrypt_pubkey,\n app_id_salt: pubkey.app_id_salt,\n });\n createSpinner.stop(true);\n\n if (!response) {\n logger.error('Failed to create CVM');\n process.exit(1);\n }\n\n logger.success('CVM created successfully');\n logger.break();\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n 'App URL': response.app_url ? response.app_url : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n\n logger.info('');\n logger.success(`Your CVM is being created. You can check its status with:\\nphala cvms get app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to create CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '../utils/constants';\nimport { TEEPod, Image, teepodSchema, imageSchema, TeepodResponse, teepodResponseSchema } from './types';\nimport { z } from 'zod';\n\n/**\n * Get all TEEPods with their images\n * @returns List of TEEPods with embedded images\n */\nexport async function getTeepods(): Promise<TEEPod[]> {\n try {\n const response = await apiClient.get<TeepodResponse>(API_ENDPOINTS.TEEPODS);\n const parsedResponse = teepodResponseSchema.parse(response);\n return parsedResponse.nodes;\n } catch (error) {\n throw new Error(`Failed to get TEEPods: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get images for a TEEPod\n * This function is maintained for backwards compatibility.\n * Images are now included directly in the TEEPod response.\n * \n * @param teepodId TEEPod ID\n * @returns List of images for the TEEPod\n */\nexport async function getTeepodImages(teepodId: string): Promise<Image[]> {\n try {\n // First try to get TEEPod with embedded images\n const teepods = await getTeepods();\n const teepod = teepods.find(pod => pod.teepod_id === Number(teepodId));\n \n // If we found the TEEPod and it has images, return them\n if (teepod && teepod.images && teepod.images.length > 0) {\n return teepod.images;\n }\n \n // Fallback to the original implementation\n const response = await apiClient.get<Image[]>(API_ENDPOINTS.TEEPOD_IMAGES(teepodId));\n return z.array(imageSchema).parse(response);\n } catch (error) {\n throw new Error(`Failed to get TEEPod images: ${error instanceof Error ? error.message : String(error)}`);\n }\n} ","import fs from 'node:fs';\nimport type { EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\n\nexport const parseEnv = (envs: string[], envFile: string): EnvVar[] => {\n // Process environment variables\n const envVars: Record<string, string> = {};\n if (envs) {\n for (const env of envs) {\n if (env.includes(\"=\")) {\n const [key, value] = env.split(\"=\");\n if (key && value) {\n envVars[key] = value;\n }\n }\n }\n }\n\n if (envFile) {\n const envFileContent = fs.readFileSync(envFile, \"utf8\");\n for (const line of envFileContent.split(\"\\n\")) {\n // Skip empty lines or comment lines\n if (!line.trim() || line.trim().startsWith('#')) continue;\n \n if (line.includes(\"=\")) {\n // Split only on the first equals sign\n const [key, ...valueParts] = line.split(\"=\");\n let value = valueParts.join(\"=\");\n \n // Remove inline comments (anything after # with whitespace before it)\n const commentIndex = value.search(/\\s+#/);\n if (commentIndex !== -1) {\n value = value.substring(0, commentIndex).trim();\n }\n \n if (key && value) {\n envVars[key.trim()] = value.trim();\n }\n }\n }\n }\n\n // Add environment variables to the payload\n return Object.entries(envVars).map(([key, value]) => ({\n key,\n value,\n }));\n};","import { Command } from 'commander';\nimport { checkCvmExists, deleteCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\n\nexport const deleteCommand = new Command()\n .name('delete')\n .description('Delete a CVM')\n .argument('[app-id]', 'App ID of the CVM to delete (if not provided, a selection prompt will appear)')\n .option('-f, --force', 'Skip confirmation prompt', false)\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n // Confirm deletion unless force option is used\n if (!options.force) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Are you sure you want to delete CVM with App ID app_${resolvedAppId}? This action cannot be undone.`,\n default: false,\n },\n ]);\n \n if (!confirm) {\n logger.info('Deletion cancelled');\n return;\n }\n }\n \n // Delete the CVM\n const spinner = logger.startSpinner(`Deleting CVM app_${resolvedAppId}`);\n const success = await deleteCvm(resolvedAppId);\n spinner.stop(true);\n \n if (!success) {\n logger.error(`Failed to delete CVM app_${resolvedAppId}`);\n process.exit(1);\n }\n\n\t\tlogger.success(`CVM app_${resolvedAppId} deleted successfully`);\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t`Failed to delete CVM: ${error instanceof Error ? error.message : String(error)}`\n\t\t);\n\t\tprocess.exit(1);\n\t}\n }); ","import { Command } from 'commander';\nimport { upgradeCvm, getCvmByAppId, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport fs from 'node:fs';\nimport { detectFileInCurrentDir, promptForFile } from '@/src/utils/prompts';\nimport { parseEnv } from '@/src/utils/secrets';\nimport { encryptEnvVars, type EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\nimport { deleteSimulatorEndpointEnv } from '@/src/utils/simulator';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const upgradeCommand = new Command()\n .name('upgrade')\n .description('Upgrade a CVM to a new version')\n .argument('[app-id]', 'CVM app ID to upgrade (will prompt for selection if not provided)')\n .option('-c, --compose <compose>', 'Path to new Docker Compose file')\n .option('-e, --env-file <envFile>', 'Path to environment file')\n .option('--debug', 'Enable debug mode', false)\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n // Get current CVM configuration\n const spinner = logger.startSpinner(`Fetching current configuration for CVM app_${resolvedAppId}`);\n const currentCvm = await getCvmByAppId(resolvedAppId);\n spinner.stop(true);\n \n if (!currentCvm) {\n logger.error(`CVM with App ID app_${resolvedAppId} not found`);\n process.exit(1);\n }\n \n // If compose path not provided, prompt with examples\n if (!options.compose) {\n const possibleFiles = ['docker-compose.yml', 'docker-compose.yaml'];\n const composeFileName = detectFileInCurrentDir(possibleFiles, 'Detected docker compose file: {path}');\n \n options.compose = await promptForFile(\n 'Enter the path to your Docker Compose file:',\n composeFileName,\n 'file'\n );\n }\n \n // Update Docker Compose file if provided\n let composeString = '';\n if (options.compose) {\n try {\n composeString = fs.readFileSync(options.compose, 'utf8');\n } catch (error) {\n logger.error(`Failed to read Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }\n \n // Delete DSTACK_SIMULATOR_ENDPOINT environment variable\n await deleteSimulatorEndpointEnv();\n\n // Process environment variables if provided\n let encrypted_env = \"\";\n if (options.envFile) {\n let envs: EnvVar[] = [];\n \n // Process environment variables from file\n if (options.envFile) {\n try {\n envs = parseEnv([], options.envFile);\n encrypted_env = await encryptEnvVars(envs, currentCvm.encrypted_env_pubkey);\n } catch (error) {\n logger.error(`Failed to read environment file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }\n \n }\n\n const vm_config = {\n compose_manifest: {\n docker_compose_file: composeString,\n manifest_version: 1,\n runner: \"docker-compose\",\n version: \"1.0.0\",\n features: [\"kms\", \"tproxy-net\"],\n name: `app_${resolvedAppId}`,\n },\n encrypted_env,\n allow_restart: true,\n };\n \n // Upgrade the CVM\n const upgradeSpinner = logger.startSpinner(`Upgrading CVM app_${resolvedAppId}`);\n const response = await upgradeCvm(resolvedAppId, vm_config);\n \n if (!response) {\n upgradeSpinner.stop(false);\n logger.error('Failed to upgrade CVM');\n process.exit(1);\n }\n upgradeSpinner.stop(true);\n\n if (response.detail) {\n logger.info(`Details: ${response.detail}`);\n }\n\n logger.break();\n logger.success(\n `Your CVM is being upgraded. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${resolvedAppId}`\n );\n } catch (error) {\n logger.error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmByAppId, resizeCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const resizeCommand = new Command()\n .name('resize')\n .description('Resize resources for a CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .option('-v, --vcpu <vcpu>', 'Number of virtual CPUs')\n .option('-m, --memory <memory>', 'Memory size in MB')\n .option('-d, --disk-size <diskSize>', 'Disk size in GB')\n .option('-r, --allow-restart <allowRestart>', 'Allow restart of the CVM if needed for resizing')\n .option('-y, --yes', 'Automatically confirm the resize operation')\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const cvm = await getCvmByAppId(resolvedAppId);\n \n // Initialize parameters\n let vcpu: number | undefined = options.vcpu;\n let memory: number | undefined = options.memory;\n let diskSize: number | undefined = options.diskSize;\n let allowRestart: boolean | undefined = options.allowRestart;\n // Prompt for vCPU if selected\n if (!vcpu) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'vcpu',\n message: 'Enter number of vCPUs:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.vcpu,\n filter: (input) => parseInt(input)\n }\n ]);\n vcpu = response.vcpu;\n }\n \n // Prompt for memory\n if (!memory) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'memory',\n message: 'Enter memory in MB:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.memory,\n filter: (input) => parseInt(input)\n }\n ]);\n memory = response.memory;\n }\n \n // Prompt for disk size\n if (!diskSize) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'diskSize',\n message: 'Enter disk size in GB:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.disk_size,\n filter: (input) => parseInt(input)\n }\n ]);\n diskSize = response.diskSize;\n }\n \n // Ask about restart permission\n if (!allowRestart) {\n const response = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'allowRestart',\n message: 'Allow restart of the CVM if needed for resizing?',\n default: false\n }\n ]);\n allowRestart = response.allowRestart;\n }\n \n // Prepare confirmation message\n const confirmMessage = `Are you sure you want to resize CVM app_${resolvedAppId} with the following changes:\\n`;\n logger.keyValueTable(\n { 'vCPUs': cvm.vcpu !== vcpu ? `${chalk.red(cvm.vcpu)} -> ${chalk.green(vcpu)}` : cvm.vcpu,\n 'Memory': cvm.memory !== memory ? `${chalk.red(cvm.memory)} MB -> ${chalk.green(memory)} MB` : cvm.memory,\n 'Disk Size': cvm.disk_size !== diskSize ? `${chalk.red(cvm.disk_size)} GB -> ${chalk.green(diskSize)} GB` : cvm.disk_size,\n 'Allow Restart': allowRestart ? chalk.green('Yes') : chalk.red('No') }\n );\n \n // Confirm the resize operation\n if (!options.yes) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: confirmMessage,\n default: false\n }\n ]);\n \n if (!confirm) {\n logger.info('Resize operation cancelled');\n return;\n }\n }\n \n const spinner = logger.startSpinner(`Resizing CVM with App ID app_${resolvedAppId}`);\n \n // Convert boolean to number (0 or 1) as expected by the API\n const allowRestartValue = allowRestart ? 1 : 0;\n \n await resizeCvm(resolvedAppId, vcpu, memory, diskSize, allowRestartValue);\n\n spinner.stop(true);\n logger.break();\n logger.success(\n `Your CVM is being resized. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${resolvedAppId}`\n );\n } catch (error) {\n logger.error(\n `Failed to resize CVM: ${error instanceof Error ? error.message : String(error)}`\n );\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { logger } from '@/src/utils/logger';\nimport { execSync } from 'node:child_process';\nimport * as os from 'node:os';\nimport { logo } from '../utils/banner';\n\n\n/**\n * Opens a URL in the default web browser based on the current operating system\n * @param url The URL to open\n */\nfunction openBrowser(url: string): void {\n const platform = os.platform();\n \n try {\n switch (platform) {\n case 'darwin': // macOS\n execSync(`open \"${url}\"`);\n break;\n case 'win32': // Windows\n execSync(`start \"\" \"${url}\"`);\n break;\n case 'linux': // Linux\n // Try different commands in order\n try {\n execSync(`xdg-open \"${url}\"`);\n } catch (error) {\n try {\n execSync(`gnome-open \"${url}\"`);\n } catch (error) {\n execSync(`kde-open \"${url}\"`);\n }\n }\n break;\n default:\n throw new Error(`Unsupported platform: ${platform}`);\n }\n logger.success(`Opened URL in your default browser: ${url}`);\n } catch (error) {\n logger.error(`Failed to open URL: ${error instanceof Error ? error.message : String(error)}`);\n logger.info(`Please manually open this URL in your browser: ${url}`);\n }\n}\n\n/**\n * Pauses execution for the specified number of milliseconds\n * @param {number} ms - Time to sleep in milliseconds\n * @returns {Promise} Promise that resolves after the specified time\n */\nfunction sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport const joinCommand = new Command()\n .name('join')\n .alias('free')\n .description('Join Phala Cloud! Get an account and deploy a CVM for FREE')\n .action(async () => {\n try {\n const inviteUrl = 'https://cloud.phala.network/register?invite=PHALACLI';\n const spinner =logger.startSpinner('Brewing a fresh cup of TEE 🍵');\n await sleep(2000);\n spinner.stop(true);\n logger.break();\n logger.break();\n console.log(logo);\n logger.info('TEE is served! Opening Phala Cloud registration page...');\n await sleep(1000);\n logger.break()\n openBrowser(inviteUrl);\n } catch (error) {\n logger.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from \"commander\";\nimport { logger } from \"@/src/utils/logger\";\nimport { getApiKey } from \"@/src/utils/credentials\";\nimport { getUserInfo } from \"@/src/api/auth\";\nimport { createCvm, getPubkeyFromCvm } from \"@/src/api/cvms\";\nimport { DEFAULT_IMAGE, CLOUD_URL } from \"@/src/utils/constants\";\nimport { demoTemplates } from \"@/src/utils/demo\";\nimport {\n\tencryptEnvVars,\n\ttype EnvVar,\n} from \"@phala/dstack-sdk/encrypt-env-vars\";\nimport inquirer from \"inquirer\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { parseEnv } from \"@/src/utils/secrets\";\n\nexport const demoCommands = new Command()\n .name(\"demo\")\n .description(\"Demo commands to launch a demo on Phala Cloud\")\n .action(async () => {\n try {\n // 1. Check if the user is logged in\n const apiKey = await getApiKey();\n if (!apiKey) {\n logger.error(\"You need to be logged in to use the demo command\");\n logger.info(\"Please login with: phala auth login\");\n process.exit(1);\n }\n\n // Verify user credentials\n try {\n const spinner = logger.startSpinner(\"Verifying your credentials\");\n const userInfo = await getUserInfo();\n spinner.stop(true);\n logger.success(`Logged in as ${userInfo.username}`);\n } catch (error) {\n logger.error(\"Authentication failed. Your API key may be invalid or expired.\");\n logger.info(\"Please set a new API key with: phala auth login\");\n process.exit(1);\n }\n\n // 2. Get list of available templates\n const templates = Object.values(demoTemplates);\n\n if (templates.length === 0) {\n logger.error(\"No template files found in the templates directory\");\n process.exit(1);\n }\n\n // 3. Prompt user to select a template\n const { selectedTemplate } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selectedTemplate\",\n message: \"Select a template to deploy:\",\n choices: templates.map(t => ({\n name: t.name,\n value: t\n }))\n }\n ]);\n\n // 4. Read the selected template\n const templateContent = selectedTemplate.compose;\n logger.success(`Selected template: ${selectedTemplate.name}`);\n\n // 5. Generate a random token for services that might need it\n const token = crypto.randomBytes(16).toString(\"hex\");\n const envVars = parseEnv([`TOKEN=${token}`], \"\");\n \n \n // 6. Ask for CVM name\n const { cvmName } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"cvmName\",\n message: \"Enter a name for your CVM:\",\n default: `${selectedTemplate.name.replace(\" \", \"-\")}`,\n validate: (input) => {\n if (!input.trim()) {\n return \"CVM name is required\";\n }\n return true;\n }\n }\n ]);\n\n // 7. Deploy the CVM with the specified resources\n logger.info(\"Preparing to deploy your CVM...\");\n \n // Prepare VM configuration with specified resources\n const vmConfig = {\n teepod_id: 3,\n name: cvmName,\n image: DEFAULT_IMAGE,\n vcpu: 2,\n memory: 2048,\n disk_size: 20,\n compose_manifest: {\n docker_compose_file: templateContent,\n docker_config: {\n url: \"\",\n username: \"\",\n password: \"\",\n },\n features: [\"kms\", \"tproxy-net\"],\n kms_enabled: true,\n manifest_version: 2,\n name: cvmName,\n public_logs: true,\n public_sysinfo: true,\n tproxy_enabled: true,\n },\n listed: false,\n };\n\n // Get public key from CVM for the API call structure\n const spinner = logger.startSpinner(\"Preparing CVM configuration\");\n const pubkey = await getPubkeyFromCvm(vmConfig);\n spinner.stop(true);\n \n if (!pubkey) {\n logger.error(\"Failed to prepare CVM configuration\");\n process.exit(1);\n }\n\n const encrypted_env = await encryptEnvVars(\n\t\t\t\t\t\t\tenvVars,\n\t\t\t\t\t\t\tpubkey.app_env_encrypt_pubkey,\n\t\t\t\t\t\t);\n\n logger.debug(\"Public key:\", pubkey.app_env_encrypt_pubkey);\n logger.debug(\"Encrypted environment variables:\", encrypted_env);\n // Create the CVM\n const createSpinner = logger.startSpinner(\"Creating your demo CVM\");\n const response = await createCvm({\n ...vmConfig,\n encrypted_env,\n app_env_encrypt_pubkey: pubkey.app_env_encrypt_pubkey,\n app_id_salt: pubkey.app_id_salt,\n });\n createSpinner.stop(true);\n\n if (!response) {\n logger.error(\"Failed to create demo CVM\");\n process.exit(1);\n }\n\n logger.success(\"Demo CVM created successfully! 🎉\");\n logger.break();\n \n const tableData = {\n \"CVM ID\": response.id,\n \"Name\": response.name,\n \"Status\": response.status,\n \"App ID\": `app_${response.app_id}`,\n \"App URL\": response.app_url ? response.app_url : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n \"Template\": selectedTemplate.name,\n \"Resources\": \"2 vCPUs, 2GB RAM, 20GB Storage\",\n };\n \n if (selectedTemplate.name.includes(\"Jupyter Notebook\")) {\n tableData[\"Jupyter Token\"] = token;\n tableData[\"Access Instructions\"] = \"Access your Jupyter notebook using the token above. Go to 'Network' tab to see the public URL.\";\n }\n \n logger.keyValueTable(tableData, {\n borderStyle: \"rounded\"\n });\n\n logger.break();\n logger.success(`Your demo is being created. You can check its status with:\\nphala cvms get app_${response.app_id}`);\n\n } catch (error) {\n logger.error(`Failed to launch demo: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n","const jupyterCompose = `version: '3'\nservices:\n jupyter:\n image: quay.io/jupyter/base-notebook\n ports:\n - 8080:8888\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n - GRANT_SUDO=yes\n user: root\n command: \"start-notebook.sh --NotebookApp.token=\\${TOKEN}\"\n`;\n\nexport const httpbinCompose = `version: '3'\nservices:\n httpbin:\n image: kennethreitz/httpbin:latest\n ports:\n - \"80:80\"\n`;\n\n\nexport const demoTemplates = {\n jupyter: {\n compose: jupyterCompose,\n name: \"Jupyter Notebook\",\n },\n httpbin: {\n compose: httpbinCompose,\n name: \"HTTPBin\",\n },\n};\n"],"mappings":"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","names":["Command","chalk","logoColor","logo","smallLogo","minimalLogo","Command","Command","fs","path","os","crypto","chalk","stripAnsi","str","pattern","getVisibleLength","wrapText","text","maxWidth","lines","currentLine","currentLineVisibleLength","words","word","wordVisibleLength","logger","message","args","data","columns","columnConfig","col","formatTable","options","mergedOptions","key","commonAcronyms","customTerms","formatted","part","acronym","regex","term","replacement","value","include","exclude","keyFormatter","valueFormatter","formatKeys","keyWidth","valueWidth","borderStyle","enableTextWrapping","maxDepth","keys","tableData","formattedValue","formatNestedObject","terminalWidth","getTerminalWidth","finalKeyWidth","finalValueWidth","item","borderChars","maxValueWidth","border","getBorderChars","topBorder","headerSeparator","row","index","keyLines","valueLines","maxLines","i","keyLine","valueLine","keyContent","valueContent","bottomBorder","success","result","icon","resultText","obj","currentDepth","style","calculateColumnWidths","borderCharsPerColumn","totalBorderWidth","availableContentWidth","initialWidths","totalFixedWidth","totalWeight","column","minWidth","contentWidth","remainingWidth","extraWidth","calculatedTotalWidth","sum","width","scale","finalWidths","formatTable","data","options","obj","keyValueData","key","col","value","parts","current","part","chalk","mergedOptions","text","columns","sample","border","columnConfig","item","widths","calculateColumnWidths","formattedColumns","index","headers","formatRow","row","rowIndex","rowData","displayValue","wrapText","maxLines","formattedLines","lineIndex","lineContent","colIndex","content","topBorder","wrappedHeaders","i","maxHeaderLines","h","headerLine","header","headerSeparator","formattedRows","rowLine","cell","rowSeparator","bottomBorder","PHALA_CLOUD_DIR","path","os","API_KEY_FILE","DOCKER_CREDENTIALS_FILE","ensureDirectoryExists","fs","error","logger","getMachineKey","machineParts","hash","crypto","encrypt","text","key","iv","cipher","encrypted","decrypt","encryptedText","parts","decipher","decrypted","saveApiKey","apiKey","encryptedApiKey","getApiKey","removeApiKey","saveDockerCredentials","credentials","getDockerCredentials","data","prompts","axios","CLOUD_API_URL","CLOUD_URL","CLI_VERSION","TEE_SIMULATOR","DEFAULT_VCPU","DEFAULT_MEMORY","DEFAULT_DISK_SIZE","DEFAULT_IMAGE","API_ENDPOINTS","teepodId","userId","appId","DOCKER_COMPOSE_ELIZA_V2_TEMPLATE","DOCKER_COMPOSE_BASIC_TEMPLATE","safeStringify","obj","error","ApiClient","baseURL","logger","axios","CLI_VERSION","config","getApiKey","response","status","data","url","CLOUD_API_URL","apiClient","z","INVALID","ParseStatus","ZodIssueCode","ZodParsedType","ZodType","addIssueToContext","z","zodDecimalKind","precisionRegex","_ZodDecimal","ZodType","input","ZodParsedType","ctx","addIssueToContext","ZodIssueCode","INVALID","status","ParseStatus","check","parts","kind","value","inclusive","message","min","ch","max","ZodDecimal","__publicField","params","ComposeTemplateSchema","z","dockerConfigSchema","z","composeFileSchema","configurationSchema","hostedSchema","managedUserSchema","nodeSchema","cvmInstanceSchema","postCvmResponseSchema","getPubkeyFromCvmResponseSchema","getCvmByAppIdResponseSchema","getUserInfoResponseSchema","ZodDecimal","getCvmsByUserIdResponseSchema","upgradeCvmResponseSchema","encryptedEnvItemSchema","imageSchema","teepodSchema","capacitySchema","teepodResponseSchema","getCvmNetworkResponseSchema","cvmAttestationResponseSchema","safeStringify","obj","error","getUserInfo","logger","API_ENDPOINTS","response","apiClient","getUserInfoResponseSchema","parseError","loginCommand","Command","apiKey","checkUserInfo","prompts","value","saveApiKey","getUserInfo","removeApiKey","logger","CLOUD_URL","error","Command","logoutCommand","Command","removeApiKey","logger","error","Command","statusCommand","Command","options","apiKey","getApiKey","logger","spinner","userInfo","getUserInfo","tableData","error","authCommands","Command","loginCommand","logoutCommand","statusCommand","Command","Command","execa","fs","path","Handlebars","exec","spawn","promisify","os","inquirer","fs","path","validateFileExists","filePath","basePath","resolvedPath","path","fs","promptForFile","message","defaultValue","name","inquirer","input","detectFileInCurrentDir","possibleFiles","logMessage","file","logger","fs","path","os","execSync","spawn","net","SIMULATOR_CONFIG","isSimulatorInstalled","platform","extractedFolderPath","executablePath","error","logger","getPlatform","installSimulator","progressCallback","log","message","platformConfig","downloadUrl","execSync","runSimulator","options","executableName","runOptions","logDir","stdio","outputStream","simulatorProcess","spawn","timestamp","setSimulatorEndpointEnv","isSimulatorRunning","platform","getPlatform","platformConfig","SIMULATOR_CONFIG","socketPath","resolve","client","host","error","logger","stopSimulator","execSync","stopped","deleteSimulatorEndpointEnv","getSimulatorEndpoint","getPlatform","setSimulatorEndpointEnv","endpoint","simulatorEndpoint","envEndpoint","execSync","logger","error","deleteSimulatorEndpointEnv","execAsync","promisify","exec","LOGS_DIR","COMPOSE_FILES_DIR","MAX_CONSOLE_LINES","DockerService","image","username","registry","logsPath","path","fs","operation","timestamp","arch","os","command","args","resolve","reject","proc","spawn","logFile","logStream","consoleBuffer","processOutput","data","isError","lines","line","bufferedLine","code","err","dockerfile","tag","fullImageName","spinner","logger","validateFileExists","buildArgs","error","imageName","getDockerCredentials","password","execa","timeoutPromise","_","checkPromise","result","envFile","templateType","template","DOCKER_COMPOSE_ELIZA_V2_TEMPLATE","DOCKER_COMPOSE_BASIC_TEMPLATE","validatedTemplate","ComposeTemplateSchema","composePath","envVars","commentIndex","key","value","trimmedKey","composeContent","Handlebars","env","composeFile","composeArgs","port","stdout","containerId","setSimulatorEndpointEnv","deleteSimulatorEndpointEnv","prompts","loginCommand","Command","options","username","password","registry","logger","response","value","dockerService","DockerService","saveDockerCredentials","error","Command","path","inquirer","fs","buildCommand","Command","options","credentials","getDockerCredentials","logger","response","inquirer","input","defaultPath","path","fs","promptForFile","dockerfilePath","DockerService","error","Command","inquirer","pushCommand","Command","options","credentials","getDockerCredentials","logger","imageName","localImages","DockerService","uniqueImageNames","img","selectedImage","error","Command","inquirer","fs","path","generateCommand","Command","options","credentials","getDockerCredentials","logger","imageName","localImages","DockerService","uniqueImageNames","img","selectedImage","inquirer","envFilePath","validateFileExists","defaultEnvPath","path","fs","useDefault","envPath","input","outputPath","confirmOverwrite","customPath","dockerService","composePath","outputDir","error","dockerCommands","Command","loginCommand","buildCommand","pushCommand","generateCommand","Command","Command","startCommand","Command","TEE_SIMULATOR","options","DockerService","logger","isSimulatorInstalled","installSimulator","isSimulatorRunning","simulatorProcess","runSimulator","error","Command","stopCommand","Command","options","DockerService","logger","stopSimulator","error","simulatorCommands","Command","startCommand","stopCommand","Command","Command","inquirer","z","getCvms","response","apiClient","API_ENDPOINTS","cvmInstanceSchema","error","checkCvmExists","appId","cvm","logger","getCvmByAppId","getCvmByAppIdResponseSchema","getPubkeyFromCvm","vmConfig","getPubkeyFromCvmResponseSchema","createCvm","vmConfig","response","apiClient","API_ENDPOINTS","postCvmResponseSchema","error","z","logger","startCvm","appId","stopCvm","restartCvm","upgradeCvm","upgradeCvmResponseSchema","deleteCvm","selectCvm","listSpinner","logger","cvms","getCvms","choices","cvm","id","name","status","selectedCvm","inquirer","getCvmAttestation","appId","response","apiClient","API_ENDPOINTS","cvmAttestationResponseSchema","validationError","error","resizeCvm","vcpu","memory","diskSize","allowRestart","resizePayload","chalk","listCommand","Command","options","spinner","logger","cvms","getCvms","cvm","CLOUD_URL","error","Command","chalk","resolveCvmAppId","appId","selectedCvm","selectCvm","checkCvmExists","getCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","spinner","logger","cvm","getCvmByAppId","chalk","CLOUD_URL","error","Command","startCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","startCvm","tableData","CLOUD_URL","error","Command","stopCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","stopCvm","tableData","CLOUD_URL","error","Command","restartCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","restartCvm","tableData","CLOUD_URL","error","Command","chalk","attestationCommand","Command","appId","options","resolvedAppId","checkCvmExists","logger","selectedCvm","selectCvm","spinner","attestationData","getCvmAttestation","summaryData","cert","index","certData","tcbBasicInfo","maxEntriesToShow","entries","entry","error","Command","z","getTeepods","response","apiClient","API_ENDPOINTS","teepodResponseSchema","error","encryptEnvVars","fs","path","inquirer","fs","parseEnv","envs","envFile","envVars","env","key","value","envFileContent","line","valueParts","commentIndex","createCommand","Command","DEFAULT_VCPU","DEFAULT_MEMORY","DEFAULT_DISK_SIZE","options","name","inquirer","input","composeFileName","detectFileInCurrentDir","promptForFile","composePath","path","fs","logger","composeString","deleteSimulatorEndpointEnv","envs","parseEnv","error","shouldSkip","envVars","vcpu","memory","diskSize","teepodsSpinner","teepods","getTeepods","selectedTeepod","pod","selectedImage","image","vmConfig","spinner","pubkey","getPubkeyFromCvm","encryptSpinner","encrypted_env","encryptEnvVars","createSpinner","response","createCvm","tableData","CLOUD_URL","Command","inquirer","deleteCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","confirm","inquirer","logger","spinner","success","deleteCvm","error","Command","fs","encryptEnvVars","upgradeCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","spinner","logger","currentCvm","getCvmByAppId","composeFileName","detectFileInCurrentDir","promptForFile","composeString","fs","error","deleteSimulatorEndpointEnv","encrypted_env","envs","parseEnv","encryptEnvVars","vm_config","upgradeSpinner","response","upgradeCvm","CLOUD_URL","Command","inquirer","chalk","resizeCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","cvm","getCvmByAppId","vcpu","memory","diskSize","allowRestart","inquirer","input","num","confirmMessage","logger","chalk","confirm","spinner","resizeCvm","CLOUD_URL","error","cvmsCommand","Command","attestationCommand","createCommand","deleteCommand","getCommand","listCommand","startCommand","stopCommand","resizeCommand","restartCommand","upgradeCommand","Command","execSync","os","openBrowser","url","platform","execSync","logger","error","sleep","ms","resolve","joinCommand","Command","inviteUrl","spinner","logo","Command","jupyterCompose","httpbinCompose","demoTemplates","encryptEnvVars","inquirer","crypto","demoCommands","Command","getApiKey","logger","spinner","userInfo","getUserInfo","templates","demoTemplates","selectedTemplate","inquirer","t","templateContent","token","crypto","envVars","parseEnv","cvmName","input","vmConfig","DEFAULT_IMAGE","pubkey","getPubkeyFromCvm","encrypted_env","encryptEnvVars","createSpinner","response","createCvm","tableData","CLOUD_URL","error","main","Command","logo","authCommands","cvmsCommand","dockerCommands","simulatorCommands","demoCommands","joinCommand","error","logger"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/banner.ts","../src/commands/auth/index.ts","../src/commands/auth/login.ts","../src/utils/credentials.ts","../src/utils/logger.ts","../src/api/client.ts","../src/utils/constants.ts","../src/api/types.ts","../src/utils/types.ts","../src/api/auth.ts","../src/commands/auth/logout.ts","../src/commands/auth/status.ts","../src/commands/docker/index.ts","../src/commands/docker/login.ts","../src/utils/docker.ts","../src/utils/prompts.ts","../src/utils/simulator.ts","../src/commands/docker/build.ts","../src/commands/docker/push.ts","../src/commands/docker/generate.ts","../src/commands/simulator/index.ts","../src/commands/simulator/start.ts","../src/commands/simulator/stop.ts","../src/commands/cvms/index.ts","../src/commands/cvms/list.ts","../src/api/cvms.ts","../src/commands/cvms/get.ts","../src/utils/cvms.ts","../src/commands/cvms/start.ts","../src/commands/cvms/stop.ts","../src/commands/cvms/restart.ts","../src/commands/cvms/attestation.ts","../src/commands/cvms/create.ts","../src/api/teepods.ts","../src/utils/secrets.ts","../src/commands/cvms/delete.ts","../src/commands/cvms/upgrade.ts","../src/commands/cvms/resize.ts","../src/commands/join.ts","../src/commands/demo/index.ts","../src/utils/demo.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { Command } from \"commander\"\nimport { logo } from \"./utils/banner\"\nimport { authCommands } from \"./commands/auth\"\nimport { dockerCommands } from \"./commands/docker\"\nimport { simulatorCommands } from \"./commands/simulator\"\nimport { logger } from \"./utils/logger\"\nimport { cvmsCommand } from './commands/cvms'\nimport { joinCommand } from \"./commands/join\"\nimport { demoCommands } from \"./commands/demo\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = new Command()\n\t\t\t.name(\"phala\")\n\t\t\t.alias(\"pha\")\n\t\t\t.description(\n\t\t\t\t`${logo}\\nPhala Cloud CLI - Manage your Phala Cloud Deployments`,\n\t\t\t)\n\t\t\t.version(\"v1.0.6\")\n\t\t\t.addCommand(authCommands)\n\t\t\t.addCommand(cvmsCommand)\n\t\t\t.addCommand(dockerCommands)\n\t\t\t.addCommand(simulatorCommands)\n\t\t\t.addCommand(demoCommands)\n\t\t\t.addCommand(joinCommand);\n\n program.parse(process.argv)\n}\n\nmain().catch((error) => {\n logger.error(\"An error occurred:\", error)\n process.exit(1)\n})","import chalk from 'chalk';\nconst logoColor = chalk.hex('#cdfa50');\nexport const logo = logoColor(`\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣤⣤⣀⡀⠀⢀⣀⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠛⠉⠁⠀⠈⠉⠛⠿⠛⠉⠉⠉⠉⠙⠷⣄⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠞⠛⠉⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⢶⣄⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣦⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣿⡿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠃⠀⢀⣾⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠋⠁⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡤⠤⠤⠴⠒⠒⠒⠒⠒⢿⡿⠓⠒⠒⠢⠤⠤⠤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣯⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⣀⣨⣿⣦⣤⣀⡀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⡏⠉⠛⣿⣆⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⣀⣀⣀⣀⡸⠿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣸⡿⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⠀⢸⣿⣿⣿⣿⡇⠀⣿⣿⣿⣿⣿⣿⠃⢀⣠⣴⡿⠃⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⠿⢇⣀⣀⣀⣀⣸⣿⣿⣿⣿⣿⡿⠿⠿⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠈⠻⢿⣿⣿⣿⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠠⣄⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⠿⣿⣿⣿⣿⣿⠿⠟⠋⠁⠀⠀⠀⠀⠀⠀⣀⣾⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⢶⣦⣤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣤⣴⣶⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠻⠿⠿⠿⠿⢿⣿⣿⣿⠿⠿⠿⠿⠟⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n`);\n\nexport const smallLogo = logoColor(`\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣤⣤⣀⡀⠀⢀⣀⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠛⠉⠁⠀⠈⠉⠛⠿⠛⠉⠉⠉⠉⠙⠷⣄⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠞⠛⠉⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⢶⣄⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣦⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣿⡿⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠃⠀⢀⣾⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠋⠁⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡤⠤⠤⠴⠒⠒⠒⠒⠒⢿⡿⠓⠒⠒⠢⠤⠤⠤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣯⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⣀⣨⣿⣦⣤⣀⡀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⡏⠉⠛⣿⣆⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⣀⣀⣀⣀⡸⠿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣸⡿⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⠀⢸⣿⣿⣿⣿⡇⠀⣿⣿⣿⣿⣿⣿⠃⢀⣠⣴⡿⠃⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⠿⢇⣀⣀⣀⣀⣸⣿⣿⣿⣿⣿⡿⠿⠿⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠈⠻⢿⣿⣿⣿⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠠⣄⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⢸⣆⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⠿⣿⣿⣿⣿⣿⠿⠟⠋⠁⠀⠀⠀⠀⠀⠀⣀⣾⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⢶⣦⣤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣤⣴⣶⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠻⠿⠿⠿⠿⢿⣿⣿⣿⠿⠿⠿⠿⠟⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n`);\n\nexport const minimalLogo = chalk.cyan('PHALA TEE CLOUD CLI');","import { Command } from 'commander';\nimport { loginCommand } from './login';\nimport { logoutCommand } from './logout';\nimport { statusCommand } from './status';\n\nexport const authCommands = new Command()\n .name('auth')\n .description('Authenticate with Phala Cloud')\n .addCommand(loginCommand)\n .addCommand(logoutCommand)\n .addCommand(statusCommand);\n","import { Command } from 'commander';\nimport { removeApiKey, saveApiKey } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport prompts from 'prompts';\nimport { getUserInfo } from '@/src/api/auth';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const loginCommand = new Command()\n .name('login')\n .description('Set the API key for authentication')\n .argument('[api-key]', 'Phala Cloud API key to set')\n .action(async (apiKey?: string) => {\n try {\n let checkUserInfo;\n // If no API key is provided, prompt for it\n if (!apiKey) {\n const response = await prompts({\n type: 'password',\n name: 'apiKey',\n message: 'Enter your API key:',\n validate: async (value) => {\n if (value.length === 0) {\n return 'API key cannot be empty';\n }\n try {\n await saveApiKey(value);\n checkUserInfo = await getUserInfo();\n if (!checkUserInfo.username) {\n await removeApiKey();\n return 'Invalid API key';\n }\n } catch (error) {\n return 'Invalid API key';\n }\n return true;\n }\n });\n \n apiKey = response.apiKey;\n } else {\n await saveApiKey(apiKey);\n // Validate the API key\n checkUserInfo = await getUserInfo();\n if (!checkUserInfo.username) {\n await removeApiKey();\n return 'Invalid API key';\n }\n }\n \n logger.success(`Welcome ${checkUserInfo.username}! API key validated and saved successfully`);\n logger.break();\n logger.info(`Open in Web UI at ${CLOUD_URL}/dashboard/`);\n } catch (error) {\n logger.error(`Failed to set API key: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport crypto from 'node:crypto';\nimport { logger } from './logger';\n\n// Define the directory and file for storing credentials\nconst PHALA_CLOUD_DIR = path.join(os.homedir(), '.phala-cloud');\nconst API_KEY_FILE = path.join(PHALA_CLOUD_DIR, 'api-key');\nconst DOCKER_CREDENTIALS_FILE = path.join(PHALA_CLOUD_DIR, 'docker-credentials.json');\n\n// Ensure the .phala-cloud directory exists\nfunction ensureDirectoryExists(): void {\n if (!fs.existsSync(PHALA_CLOUD_DIR)) {\n try {\n fs.mkdirSync(PHALA_CLOUD_DIR, { recursive: true });\n } catch (error) {\n logger.error(`Failed to create directory ${PHALA_CLOUD_DIR}:`, error);\n throw error;\n }\n }\n}\n\n// Generate a machine-specific encryption key\nfunction getMachineKey(): Buffer {\n // Create a deterministic but machine-specific key\n const machineParts = [\n os.hostname(),\n os.platform(),\n os.arch(),\n os.cpus()[0]?.model || '',\n os.userInfo().username\n ];\n \n // Create a hash of the machine parts\n const hash = crypto.createHash('sha256');\n hash.update(machineParts.join('|'));\n return hash.digest();\n}\n\n// Encrypt data\nfunction encrypt(text: string): string {\n try {\n const key = getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key.slice(0, 32), iv);\n \n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n // Return IV + encrypted data\n return iv.toString('hex') + ':' + encrypted;\n } catch (error) {\n logger.error('Encryption failed:', error);\n throw new Error('Failed to encrypt data');\n }\n}\n\n// Decrypt data\nfunction decrypt(encryptedText: string): string {\n try {\n const key = getMachineKey();\n const parts = encryptedText.split(':');\n \n if (parts.length !== 2) {\n throw new Error('Invalid encrypted format');\n }\n \n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n \n const decipher = crypto.createDecipheriv('aes-256-cbc', key.slice(0, 32), iv);\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n } catch (error) {\n logger.error('Decryption failed:', error);\n throw new Error('Failed to decrypt data');\n }\n}\n\n// API Key Management\nexport async function saveApiKey(apiKey: string): Promise<void> {\n ensureDirectoryExists();\n try {\n // Encrypt the API key before saving\n const encryptedApiKey = encrypt(apiKey);\n fs.writeFileSync(API_KEY_FILE, encryptedApiKey, { mode: 0o600 }); // Restrict permissions to user only\n } catch (error) {\n logger.error('Failed to save API key:', error);\n throw error;\n }\n}\n\nexport async function getApiKey(): Promise<string | null> {\n try {\n if (fs.existsSync(API_KEY_FILE)) {\n const encryptedApiKey = fs.readFileSync(API_KEY_FILE, 'utf8').trim();\n // Decrypt the API key\n return decrypt(encryptedApiKey);\n }\n return null;\n } catch (error) {\n logger.error('Failed to read API key:', error);\n return null;\n }\n}\n\nexport async function removeApiKey(): Promise<void> {\n try {\n if (fs.existsSync(API_KEY_FILE)) {\n fs.unlinkSync(API_KEY_FILE);\n logger.success('API key removed successfully.');\n } else {\n logger.warn('No API key found to remove.');\n }\n } catch (error) {\n logger.error('Failed to remove API key:', error);\n throw error;\n }\n}\n\n// Docker Credentials Management\ninterface DockerCredentials {\n username: string;\n registry?: string;\n}\n\nexport async function saveDockerCredentials(credentials: DockerCredentials): Promise<void> {\n ensureDirectoryExists();\n try {\n \n fs.writeFileSync(\n DOCKER_CREDENTIALS_FILE, \n JSON.stringify(credentials, null, 2), \n { mode: 0o600 } // Restrict permissions to user only\n );\n logger.success('Docker information saved successfully.');\n } catch (error) {\n logger.error('Failed to save Docker information:', error);\n throw error;\n }\n}\n\nexport async function getDockerCredentials(): Promise<DockerCredentials | null> {\n try {\n if (fs.existsSync(DOCKER_CREDENTIALS_FILE)) {\n const data = fs.readFileSync(DOCKER_CREDENTIALS_FILE, 'utf8');\n const credentials = JSON.parse(data) as DockerCredentials;\n \n return credentials;\n }\n return null;\n } catch (error) {\n logger.error('Failed to read Docker credentials:', error);\n return null;\n }\n}\n\nexport async function removeDockerCredentials(): Promise<void> {\n try {\n if (fs.existsSync(DOCKER_CREDENTIALS_FILE)) {\n fs.unlinkSync(DOCKER_CREDENTIALS_FILE);\n logger.success('Docker credentials removed successfully.');\n } else {\n logger.warn('No Docker credentials found to remove.');\n }\n } catch (error) {\n logger.error('Failed to remove Docker credentials:', error);\n throw error;\n }\n} ","import chalk from \"chalk\"\n\n/**\n * Strips ANSI color escape sequences from a string to get its visible length\n * @param str String that may contain ANSI color codes\n * @returns String with all ANSI color codes removed\n */\nfunction stripAnsi(str: string): string {\n // ANSI escape sequence regex pattern\n const pattern = [\n '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)',\n '(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TZcf-ntqry=><~]))'\n ].join('|');\n return str.replace(new RegExp(pattern, 'g'), '');\n}\n\n/**\n * Gets the visible length of a string, ignoring ANSI color codes\n * @param str String that may contain ANSI color codes\n * @returns Visible length of the string\n */\nfunction getVisibleLength(str: string): number {\n return stripAnsi(str).length;\n}\n\n/**\n * Wraps text to fit within a specified width\n * @param text Text to wrap\n * @param maxWidth Maximum width for the text\n * @returns Array of lines of text\n */\nfunction wrapText(text: string, maxWidth: number): string[] {\n if (!text) return [''];\n \n // Handle case where a single word is longer than maxWidth\n if (getVisibleLength(text) <= maxWidth) return [text];\n \n const lines: string[] = [];\n let currentLine = '';\n let currentLineVisibleLength = 0;\n \n // Split by any whitespace and preserve URLs\n const words = text.split(/(\\s+)/).filter(word => word.trim().length > 0);\n \n for (const word of words) {\n const wordVisibleLength = getVisibleLength(word);\n \n // If the word itself is longer than maxWidth, split it\n if (wordVisibleLength > maxWidth) {\n if (currentLine) {\n lines.push(currentLine);\n currentLine = '';\n currentLineVisibleLength = 0;\n }\n \n // This is a simplification as it's complex to split words with color codes\n // For long colored words, we'll just add them as-is\n lines.push(word);\n continue;\n }\n \n // If adding the word would exceed maxWidth\n if (currentLineVisibleLength + wordVisibleLength + (currentLineVisibleLength > 0 ? 1 : 0) > maxWidth) {\n lines.push(currentLine);\n currentLine = word;\n currentLineVisibleLength = wordVisibleLength;\n } else {\n // Add word to current line\n if (currentLine) {\n currentLine = `${currentLine} ${word}`;\n currentLineVisibleLength += wordVisibleLength + 1; // +1 for space\n } else {\n currentLine = word;\n currentLineVisibleLength = wordVisibleLength;\n }\n }\n }\n \n if (currentLine) {\n lines.push(currentLine);\n }\n \n return lines;\n}\n\nexport const logger = {\n error: (message: string, ...args: any[]) => {\n console.error(chalk.red('✗'), chalk.red(message), ...args)\n },\n warn: (message: string, ...args: any[]) => {\n console.log(chalk.yellow('⚠'), chalk.yellow(message), ...args)\n },\n info: (message: string, ...args: any[]) => {\n console.log(chalk.blue('ℹ'), chalk.blue(message), ...args)\n },\n success: (message: string, ...args: any[]) => {\n console.log(chalk.green('✓'), chalk.green(message), ...args)\n },\n debug: (message: string, ...args: any[]) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray('🔍'), chalk.gray(message), ...args)\n }\n },\n table: <T>(\n data: T[], \n columns?: Array<string> | Array<{ key: keyof T | string, header?: string }> | Array<any>\n ) => {\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n \n // Support for old API with just column names\n if (columns) {\n if (typeof columns[0] === 'string') {\n // Convert simple string array to column config\n const columnConfig = (columns as string[]).map(col => ({\n key: col,\n header: col.charAt(0).toUpperCase() + col.slice(1) // Capitalize\n }));\n \n // Filter data to only include specified columns\n formatTable(data, { \n columns: columnConfig,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n } else {\n // Using the new column config format\n formatTable(data, { \n columns: columns as Array<{ key: keyof T | string, header?: string }>,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n } else {\n // No columns specified, show all\n formatTable(data, {\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n },\n /**\n * Displays an object's properties in a key-value table format (vertical table)\n * @param data Object to display\n * @param options Table display options\n */\n keyValueTable: <T extends object>(\n data: T,\n options?: {\n include?: string[]; // Optional list of keys to include\n exclude?: string[]; // Optional list of keys to exclude\n keyFormatter?: (key: string) => string; // Optional formatter for keys\n valueFormatter?: (value: any, key: string) => string; // Optional formatter for values\n formatKeys?: boolean; // Whether to format keys (default: true)\n keyHeader?: string; // Optional header for the key column\n valueHeader?: string; // Optional header for the value column\n keyWidth?: number; // Optional fixed width for the key column\n valueWidth?: number; // Optional fixed width for the value column\n borderStyle?: 'single' | 'double' | 'rounded'; // Border style\n enableTextWrapping?: boolean; // Whether to wrap text\n maxDepth?: number; // Maximum depth for nested objects (default: 2)\n }\n ) => {\n // Default options\n const defaultOptions = {\n borderStyle: 'rounded' as const,\n enableTextWrapping: true,\n maxDepth: 2,\n formatKeys: true,\n // Improved key formatter with different formatting options\n keyFormatter: (key: string) => {\n // Common acronyms that should remain uppercase\n const commonAcronyms = [\n 'URL', 'ID', 'API', 'UI', 'URI', 'CPU', 'GPU', 'RAM', 'JSON', 'XML', 'HTML', \n 'HTTP', 'HTTPS', 'SSH', 'FTP', 'IP', 'TCP', 'UDP', 'DNS', 'SSL', 'TLS', 'SQL', \n 'VCPU', 'CVM', 'TEE', 'IO'\n ];\n \n // Phala-specific terms with custom capitalization\n const customTerms = {\n 'teepod': 'TEEPod',\n 'dstack': 'Dstack'\n };\n \n // Handle different cases\n let formatted;\n \n if (key.includes('_')) {\n // Handle snake_case: convert app_url to App Url\n formatted = key.split('_')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else if (key.includes('-')) {\n // Handle kebab-case: convert app-url to App Url\n formatted = key.split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else {\n // Handle camelCase: convert appUrl to App Url\n formatted = key.charAt(0).toUpperCase() + \n key.slice(1).replace(/([a-z])([A-Z])/g, '$1 $2');\n }\n \n // Replace common acronyms in the formatted text, preserving case\n for (const acronym of commonAcronyms) {\n // Only uppercase the whole acronym if it appears as a whole word\n const regex = new RegExp(`\\\\b${acronym.toLowerCase()}\\\\b`, 'gi');\n formatted = formatted.replace(regex, acronym);\n }\n \n // Apply custom term formatting\n for (const [term, replacement] of Object.entries(customTerms)) {\n const regex = new RegExp(`\\\\b${term}\\\\b`, 'gi');\n formatted = formatted.replace(regex, replacement);\n }\n \n return formatted;\n },\n valueFormatter: (value: any) => String(value ?? '')\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n const { include, exclude, keyFormatter, valueFormatter, formatKeys, keyWidth, valueWidth, borderStyle, enableTextWrapping, maxDepth } = mergedOptions;\n\n // Extract keys based on include/exclude\n let keys = Object.keys(data);\n if (include) {\n keys = keys.filter(key => include.includes(key));\n }\n if (exclude) {\n keys = keys.filter(key => !exclude.includes(key));\n }\n\n // If no keys to display, show message and return\n if (keys.length === 0) {\n console.log(chalk.yellow('No properties to display'));\n return;\n }\n\n // Prepare the data array for the table formatter\n const tableData = keys.map(key => {\n const value = data[key as keyof T];\n \n // Format the value based on its type\n let formattedValue: string;\n if (value === null || value === undefined) {\n formattedValue = '';\n } else if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle nested objects (but limit depth)\n formattedValue = formatNestedObject(value, 0, maxDepth);\n } else if (Array.isArray(value)) {\n // Handle arrays\n if (value.length === 0) {\n formattedValue = '[]';\n } else if (typeof value[0] === 'object') {\n // Array of objects\n formattedValue = `[${value.length} items]`;\n } else {\n // Array of primitives\n formattedValue = `[${value.join(', ')}]`;\n }\n } else {\n // Handle primitives\n formattedValue = String(value);\n }\n \n // Apply custom value formatter if provided\n if (valueFormatter) {\n formattedValue = valueFormatter(value, key);\n }\n \n return {\n key: formatKeys && keyFormatter ? chalk.cyan.bold(keyFormatter(key)) : chalk.cyan.bold(key),\n value: formattedValue\n };\n });\n\n // Calculate column widths based on content\n const terminalWidth = getTerminalWidth();\n let finalKeyWidth = keyWidth;\n let finalValueWidth = valueWidth;\n \n // Calculate key column width based on content if not specified\n if (!finalKeyWidth) {\n finalKeyWidth = Math.max(\n ...tableData.map(item => getVisibleLength(item.key)),\n 10 // Minimum key width\n );\n // Limit to 1/3 of terminal width\n finalKeyWidth = Math.min(finalKeyWidth, Math.floor(terminalWidth / 3));\n }\n \n // Calculate value column width based on content if not specified\n if (!finalValueWidth) {\n // Calculate based on actual content lengths\n finalValueWidth = Math.max(\n ...tableData.map(item => getVisibleLength(item.value)),\n 10 // Minimum value width\n );\n \n // Add some padding for readability (3 chars)\n finalValueWidth += 3;\n \n // Ensure we don't exceed terminal width\n const borderChars = 7; // Typical border chars count\n const maxValueWidth = terminalWidth - finalKeyWidth - borderChars;\n finalValueWidth = Math.min(finalValueWidth, maxValueWidth);\n }\n\n // Configure border characters based on style\n const border = getBorderChars(borderStyle);\n\n // Header row\n const topBorder = `${border.topLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.topT}${border.horizontal.repeat(finalValueWidth + 2)}${border.topRight}`;\n const headerSeparator = `${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`;\n \n console.log(topBorder);\n console.log(headerSeparator);\n \n // Data rows\n tableData.forEach((row, index) => {\n const keyLines = enableTextWrapping ? wrapText(row.key, finalKeyWidth) : [row.key];\n const valueLines = enableTextWrapping ? wrapText(row.value, finalValueWidth) : [row.value];\n \n const maxLines = Math.max(keyLines.length, valueLines.length);\n \n for (let i = 0; i < maxLines; i++) {\n const keyLine = keyLines[i] || '';\n const valueLine = valueLines[i] || '';\n \n // Pad with spaces to align columns, accounting for invisible ANSI characters\n const keyContent = keyLine + ' '.repeat(Math.max(0, finalKeyWidth - getVisibleLength(keyLine)));\n const valueContent = valueLine + ' '.repeat(Math.max(0, finalValueWidth - getVisibleLength(valueLine)));\n \n console.log(`${border.vertical} ${keyContent} ${border.vertical} ${valueContent} ${border.vertical}`);\n }\n \n // Add a separator between rows, but not after the last row\n if (index < tableData.length - 1) {\n console.log(`${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`);\n }\n });\n \n // Bottom border\n const bottomBorder = `${border.bottomLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.bottomT}${border.horizontal.repeat(finalValueWidth + 2)}${border.bottomRight}`;\n console.log(bottomBorder);\n },\n startSpinner: (message: string) => {\n process.stdout.write(`${chalk.blue('⟳')} ${message}... `)\n return {\n stop: (success = true, result?: string) => {\n const icon = success ? chalk.green('✓') : chalk.red('✗')\n const resultText = result ? `: ${result}` : ''\n console.log(`${icon}${resultText}`)\n }\n }\n },\n break() {\n console.log(\"\")\n },\n}\n\n/**\n * Formats a nested object for display in the keyValueTable\n */\nfunction formatNestedObject(obj: any, currentDepth: number, maxDepth: number): string {\n if (currentDepth >= maxDepth) {\n return '[Nested Object]';\n }\n \n if (obj === null || obj === undefined) {\n return '';\n }\n \n if (Array.isArray(obj)) {\n if (obj.length === 0) return '[]';\n return `[${obj.length} items]`;\n }\n \n const lines: string[] = [];\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) {\n lines.push(`${key}: `);\n } else if (typeof value === 'object') {\n lines.push(`${key}: ${formatNestedObject(value, currentDepth + 1, maxDepth)}`);\n } else {\n lines.push(`${key}: ${value}`);\n }\n }\n \n return lines.join(', ');\n}\n\n/**\n * Get border characters based on style\n */\nfunction getBorderChars(style: 'single' | 'double' | 'rounded' = 'single') {\n return {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n }[style];\n}\n\nfunction getTerminalWidth(): number {\n return process.stdout.columns || 80; // Default to 80 if width cannot be determined\n}\n\n/**\n * Calculate column widths for tabular data display\n * @param data Array of objects to display in table\n * @param columns Configuration for each column to display\n * @param options Additional display options\n * @returns Object with calculated widths for each column\n */\nexport function calculateColumnWidths<T>(\n data: T[],\n columns: {\n key: keyof T;\n header: string;\n minWidth?: number;\n weight?: number; // Relative weight for distributing remaining space (default: 1)\n fixedWidth?: number; // If set, this column will have exactly this width\n getValue?: (item: T) => string; // Custom accessor for nested properties\n getWidth?: (item: T) => number; // Custom width calculator\n }[],\n options: {\n borderChars?: number; // Characters used for borders per column\n additionalBorderWidth?: number; // Additional border width (outer borders, etc.)\n } = {}\n): { [key: string]: number } {\n const terminalWidth = getTerminalWidth();\n \n // Calculate total border width\n const borderCharsPerColumn = options.borderChars ?? 3; // Default \"| \" + \" \" per column\n const additionalBorderWidth = options.additionalBorderWidth ?? 1; // Default \"|\" at the end\n const totalBorderWidth = additionalBorderWidth + columns.length * borderCharsPerColumn;\n \n const availableContentWidth = terminalWidth - totalBorderWidth;\n \n // Calculate initial widths based on content and minimum requirements\n const initialWidths: { [key: string]: number } = {};\n let totalFixedWidth = 0;\n let totalWeight = 0;\n \n // First pass: Calculate initial widths and total weight\n for (const column of columns) {\n const key = column.key as string;\n \n if (column.fixedWidth !== undefined) {\n initialWidths[key] = column.fixedWidth;\n totalFixedWidth += column.fixedWidth;\n continue;\n }\n \n const minWidth = column.minWidth ?? column.header.length;\n \n let contentWidth: number;\n if (column.getWidth) {\n // Use custom width calculator if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => column.getWidth!(item))\n );\n } else if (column.getValue) {\n // Use custom accessor if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(column.getValue!(item) || '').length)\n );\n } else {\n // Default behavior\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(item[column.key] || '').length)\n );\n }\n \n initialWidths[key] = contentWidth;\n totalFixedWidth += contentWidth;\n totalWeight += column.weight ?? 1;\n }\n \n // Calculate remaining width to distribute\n const remainingWidth = Math.max(0, availableContentWidth - totalFixedWidth);\n \n // If we have remaining width and weights, distribute according to weights\n if (remainingWidth > 0 && totalWeight > 0) {\n for (const column of columns) {\n const key = column.key as string;\n if (column.fixedWidth === undefined && column.weight) {\n const extraWidth = Math.floor(remainingWidth * (column.weight / totalWeight));\n initialWidths[key] += extraWidth;\n }\n }\n }\n \n // If total width would exceed terminal, scale everything down proportionally\n const calculatedTotalWidth = Object.values(initialWidths).reduce((sum, width) => sum + width, 0) + totalBorderWidth;\n \n if (calculatedTotalWidth > terminalWidth) {\n const scale = availableContentWidth / (calculatedTotalWidth - totalBorderWidth);\n \n const finalWidths: { [key: string]: number } = {};\n for (const column of columns) {\n const key = column.key as string;\n const minWidth = column.minWidth ?? column.header.length;\n finalWidths[key] = Math.max(minWidth, Math.floor(initialWidths[key] * scale));\n }\n \n return finalWidths;\n }\n \n return initialWidths;\n}\n\n/**\n * Example of how to use calculateColumnWidths with nested objects\n * @param data Array of objects with nested properties\n * @returns Object with calculated column widths\n */\nexport function calculateNestedTableWidths<T>(\n data: T[],\n columns: Array<{\n key: string; // Output key in the result object\n header: string;\n minWidth: number;\n weight?: number;\n accessor: (item: T) => string; // Function to access the nested property\n }>\n): { [key: string]: number } {\n // Convert to the format expected by calculateColumnWidths\n const columnConfig = columns.map((col, index) => ({\n key: `col_${index}` as keyof T, // Use a unique key for each column\n header: col.header,\n minWidth: col.minWidth,\n weight: col.weight,\n getValue: col.accessor\n }));\n\n // Get the raw widths\n const widths = calculateColumnWidths(data, columnConfig, { borderChars: 3, additionalBorderWidth: 1 });\n \n // Remap to expected keys\n const result: { [key: string]: number } = {};\n columns.forEach((col, index) => {\n result[col.key] = widths[`col_${index}` as string];\n });\n \n return result;\n}\n\n/**\n * Format and display data as a table in the terminal with customizable styling\n * @param data Array of objects to display in table\n * @param options Table display options\n */\nexport function formatTable<T>(\n data: T[],\n options: {\n columns?: Array<{\n key: keyof T | string;\n header?: string;\n minWidth?: number;\n weight?: number;\n accessor?: (item: T) => any;\n formatter?: (value: any) => string;\n enableTextWrapping?: boolean; // Changed from wrapText to enableTextWrapping\n }>;\n includeHeaders?: boolean;\n border?: boolean;\n borderStyle?: 'single' | 'double' | 'rounded';\n headerStyle?: (text: string) => string;\n cellStyle?: (text: string, rowIndex: number, colKey: string) => string;\n enableTextWrapping?: boolean; // Global option to control text wrapping\n keyValueMode?: boolean; // Option to display a single object in key-value rows\n } = {}\n): void {\n // If in key-value mode, transform the data\n if (options.keyValueMode && data.length === 1) {\n const obj = data[0];\n const keyValueData: Array<{key: string, value: any}> = [];\n \n // Generate columns if not provided\n if (!options.columns) {\n options.columns = Object.keys(obj).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1') // Capitalize and add spaces\n }));\n }\n \n // Transform object to key-value rows\n for (const col of options.columns) {\n const key = String(col.key);\n let value;\n \n if (col.accessor) {\n value = col.accessor(obj);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current;\n } else {\n value = obj[col.key as keyof T];\n }\n \n // Apply formatter if provided\n if (col.formatter) {\n value = col.formatter(value);\n }\n \n keyValueData.push({\n key: col.header || key,\n value: value\n });\n }\n \n // Replace data and columns\n data = keyValueData as unknown as T[];\n options.columns = [\n { key: 'key' as keyof T, minWidth: 15 },\n { key: 'value' as keyof T, minWidth: 20 }\n ];\n }\n\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n\n // Default options\n const defaultOptions = {\n includeHeaders: true,\n border: true,\n borderStyle: 'single' as const,\n headerStyle: (text: string) => chalk.bold(text),\n cellStyle: (text: string) => text,\n enableTextWrapping: true // Enable text wrapping by default\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n\n // Auto-generate columns if not provided\n let columns = mergedOptions.columns;\n if (!columns) {\n const sample = data[0];\n columns = Object.keys(sample).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize header\n enableTextWrapping: mergedOptions.enableTextWrapping\n }));\n } else {\n // Ensure all columns have enableTextWrapping property set if not explicitly defined\n columns = columns.map(col => ({\n ...col,\n enableTextWrapping: col.enableTextWrapping !== undefined ? col.enableTextWrapping : mergedOptions.enableTextWrapping\n }));\n }\n\n // Configure border characters based on style\n const borderChars = {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n };\n\n const border = borderChars[mergedOptions.borderStyle];\n\n // Configure column config for width calculation\n const columnConfig = columns.map(col => ({\n key: col.key as keyof T,\n header: col.header || String(col.key),\n minWidth: col.minWidth || 3,\n weight: col.weight,\n enableTextWrapping: col.enableTextWrapping,\n getValue: col.accessor ? \n (item: T) => col.accessor!(item) : \n (item: T) => {\n // Handle dot notation for nested objects\n if (typeof col.key === 'string' && col.key.includes('.')) {\n const parts = col.key.split('.');\n let value: any = item;\n for (const part of parts) {\n if (value === null || value === undefined) return '';\n value = value[part as keyof typeof value];\n }\n return value ?? '';\n }\n return item[col.key as keyof T] ?? '';\n }\n }));\n\n // Calculate column widths\n const widths = calculateColumnWidths(data, columnConfig);\n\n // Prepare column and header arrays with proper keys\n const formattedColumns = columns.map((col, index) => ({\n ...col,\n width: widths[columnConfig[index].key as string]\n }));\n\n // Format headers and rows\n const headers = formattedColumns.map(col => col.header || String(col.key));\n \n // Helper to format a row with text wrapping support\n const formatRow = (row: T, rowIndex: number) => {\n // For each column, get the value and wrap it if needed\n const rowData = formattedColumns.map(col => {\n let value;\n if (col.accessor) {\n value = col.accessor(row);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = row;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current ?? '';\n } else {\n value = row[col.key as keyof T] ?? '';\n }\n \n // Format the value\n let displayValue = col.formatter ? col.formatter(value) : String(value || '');\n \n // Wrap text if enabled for this column\n if (col.enableTextWrapping) {\n return {\n lines: wrapText(displayValue, col.width),\n key: String(col.key)\n };\n }\n // Truncate if not wrapping\n return {\n lines: [displayValue.length > col.width ? \n displayValue.substring(0, col.width - 1) + '…' : \n displayValue],\n key: String(col.key)\n };\n });\n \n // Calculate the maximum number of lines in any column for this row\n const maxLines = Math.max(...rowData.map(col => col.lines.length));\n \n // Format each line of the row\n const formattedLines = [];\n for (let lineIndex = 0; lineIndex < maxLines; lineIndex++) {\n const lineContent = rowData.map((col, colIndex) => {\n const content = col.lines[lineIndex] || '';\n return mergedOptions.cellStyle(\n content.padEnd(formattedColumns[colIndex].width), \n rowIndex, \n col.key\n );\n });\n formattedLines.push(lineContent);\n }\n \n return formattedLines;\n };\n\n // Generate table parts\n if (mergedOptions.border) {\n // Top border\n const topBorder = border.topLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.topT) +\n border.topRight;\n console.log(topBorder);\n \n // Headers with possible wrapping\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = border.vertical + \n wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return ' ' + mergedOptions.headerStyle(content.padEnd(header.width)) + ' ';\n }).join(border.vertical) + \n border.vertical;\n console.log(headerLine);\n }\n \n // Header-data separator\n const headerSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(\n border.vertical + \n rowLine.map(cell => ` ${cell} `).join(border.vertical) + \n border.vertical\n );\n });\n \n // Optional: Add a separator between rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n const rowSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(rowSeparator);\n }\n });\n \n // Bottom border\n const bottomBorder = border.bottomLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.bottomT) +\n border.bottomRight;\n console.log(bottomBorder);\n } else {\n // No borders, simpler display\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return mergedOptions.headerStyle(content.padEnd(header.width));\n }).join(' ');\n console.log(headerLine);\n }\n \n // Simple underline for headers\n const headerSeparator = formattedColumns.map(col => \n '─'.repeat(col.width)\n ).join(' ');\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(rowLine.join(' '));\n });\n \n // Add a blank line between multi-line rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n console.log('');\n }\n });\n }\n \n console.log(`Total: ${data.length} rows`);\n}\n\n","import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { getApiKey } from '../utils/credentials';\nimport { logger } from '../utils/logger';\nimport { CLOUD_API_URL, CLI_VERSION } from '../utils/constants';\n\n// Helper function to safely stringify objects that might contain cyclic references\nfunction safeStringify(obj: any): string {\n try {\n return JSON.stringify(obj);\n } catch (error) {\n if (error instanceof Error && error.message.includes('cyclic')) {\n return '[Cyclic Object]';\n }\n return String(obj);\n }\n}\n\nexport class ApiClient {\n private client: AxiosInstance;\n private apiKey: string | null = null;\n\n constructor(baseURL: string) {\n logger.debug(`Creating API client with base URL: ${baseURL}`);\n \n this.client = axios.create({\n baseURL,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `tee-cloud-cli/${CLI_VERSION}`,\n },\n });\n\n // Add request interceptor to include API key\n this.client.interceptors.request.use(async (config) => {\n if (!this.apiKey) {\n this.apiKey = await getApiKey();\n if (!this.apiKey) {\n throw new Error('API key not found. Please set an API key first with \"phala auth login\"');\n }\n logger.debug(`API key loaded: ${this.apiKey.substring(0, 5)}...`);\n }\n \n config.headers['X-API-Key'] = this.apiKey;\n logger.debug(`Making request to: ${config.baseURL}${config.url}`);\n return config;\n });\n\n // Add response interceptor for error handling\n this.client.interceptors.response.use(\n (response) => {\n logger.debug(`Received successful response from: ${response.config.url}`);\n return response;\n },\n (error) => {\n if (error.response) {\n const { status, data } = error.response;\n \n logger.debug(`Received error response: ${status} - ${safeStringify(data)}`);\n \n if (status === 401) {\n logger.error('Authentication failed. Please check your API key.');\n } else if (status === 403) {\n logger.error('You do not have permission to perform this action.');\n } else if (status === 404) {\n logger.error('Resource not found.');\n } else {\n logger.error(`API Error (${status}): ${data.message || safeStringify(data)}`);\n }\n } else if (error.request) {\n logger.error('No response received from the server. Please check your internet connection.');\n logger.debug(`Request details: ${safeStringify(error.request).substring(0, 200)}...`);\n } else {\n logger.error(`Error: ${error.message}`);\n }\n \n return Promise.reject(error);\n }\n );\n }\n\n async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`GET request to: ${url}`);\n const response = await this.client.get<T>(url, config);\n return response.data;\n } catch (error) {\n logger.debug(`GET request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`POST request to: ${url}`);\n const response = await this.client.post<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`POST request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`PUT request to: ${url}`);\n const response = await this.client.put<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`PUT request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`DELETE request to: ${url}`);\n const response = await this.client.delete<T>(url, config);\n return response.data;\n } catch (error) {\n logger.debug(`DELETE request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n\n async patch<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {\n try {\n logger.debug(`PATCH request to: ${url}`);\n const response = await this.client.patch<T>(url, data, config);\n return response.data;\n } catch (error) {\n logger.debug(`PATCH request failed: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n}\n\n// Create and export a singleton instance\nlogger.debug(`Initializing API client with URL: ${CLOUD_API_URL}`);\nexport const apiClient = new ApiClient(CLOUD_API_URL); ","// API URLs\nexport const CLOUD_API_URL = process.env.CLOUD_API_URL || 'https://cloud-api.phala.network';\nexport const CLOUD_URL = process.env.CLOUD_URL || 'https://cloud.phala.network';\n\n// CLI Version\nexport const CLI_VERSION = '0.0.1';\n\n// Docker Hub API\nexport const DOCKER_HUB_API_URL = 'https://hub.docker.com/v2';\n\n// TEE Simulator\nexport const TEE_SIMULATOR = 'phalanetwork/tappd-simulator:latest';\n\n// Default resource configurations\nexport const DEFAULT_VCPU = 2;\nexport const DEFAULT_MEMORY = 4096; // MB\nexport const DEFAULT_DISK_SIZE = 40; // GB\n\n// Default TEEPod ID\nexport const DEFAULT_TEEPOD_ID = '3';\nexport const DEFAULT_IMAGE = 'dstack-0.3.5';\n\n// API Endpoints\nexport const API_ENDPOINTS = {\n // Auth\n USER_INFO: '/api/v1/auth/me',\n\n // TEEPods\n TEEPODS: '/api/v1/teepods/available',\n TEEPOD_IMAGES: (teepodId: string) => `/api/v1/teepods/${teepodId}/images`,\n \n // CVMs\n CVMS: (userId: number) => `/api/v1/cvms?user_id=${userId}`,\n CVM_BY_APP_ID: (appId: string) => `/api/v1/cvms/app_${appId}`,\n CVM_NETWORK: (appId: string) => `/api/v1/cvms/app_${appId}/network`,\n CVM_START: (appId: string) => `/api/v1/cvms/app_${appId}/start`,\n CVM_STOP: (appId: string) => `/api/v1/cvms/app_${appId}/stop`,\n CVM_RESTART: (appId: string) => `/api/v1/cvms/app_${appId}/restart`,\n CVM_LOGS: (appId: string) => `/api/v1/cvms/app_${appId}/logs`,\n CVM_FROM_CONFIGURATION: '/api/v1/cvms/from_cvm_configuration',\n CVM_PUBKEY: '/api/v1/cvms/pubkey/from_cvm_configuration',\n CVM_UPGRADE: (appId: string) => `/api/v1/cvms/app_${appId}/compose`,\n CVM_ATTESTATION: (appId: string) => `/api/v1/cvms/app_${appId}/attestation`,\n CVM_RESIZE: (appId: string) => `/api/v1/cvms/app_${appId}/resources`,\n};\n\nexport const DOCKER_COMPOSE_ELIZA_V2_TEMPLATE = `version: '3.8'\nservices:\n postgres:\n image: ankane/pgvector:latest\n environment:\n - POSTGRES_PASSWORD=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_DB=eliza\n - PGDATA=/var/lib/postgresql/data/pgdata\n volumes:\n - postgres-data:/var/lib/postgresql/data:rw\n ports:\n - \"127.0.0.1:5432:5432\"\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U \\${POSTGRES_USER} -d \\${POSTGRES_DB}\"]\n interval: 5s\n timeout: 5s\n retries: 5\n restart: always\n networks:\n - eliza-network\n eliza:\n image: {{imageName}}\n command: bun run start\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n{{#each envVars}} - {{{this}}}\n{{/each}}\n ports:\n - \"3000:3000\"\n depends_on:\n postgres:\n condition: service_healthy\n restart: always\n networks:\n - eliza-network\n\n\nnetworks:\n eliza-network:\n driver: bridge\n\nvolumes:\n postgres-data:`;\n\nexport const DOCKER_COMPOSE_BASIC_TEMPLATE = `version: '3.8'\nservices:\n app:\n image: {{imageName}}\n container_name: app\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n{{#each envVars}} - {{{this}}}\n{{/each}}\n restart: always\n`","import { z } from 'zod';\nimport { ZodDecimal as zodDecimal } from '../utils/types';\n// Docker Config Schema\nexport const dockerConfigSchema = z.object({\n password: z.string(),\n registry: z.string().nullable(),\n username: z.string()\n});\n\n// Compose File Schema\nexport const composeFileSchema = z.object({\n docker_compose_file: z.string(),\n docker_config: dockerConfigSchema.optional(),\n features: z.array(z.string()),\n kms_enabled: z.boolean(),\n manifest_version: z.number(),\n name: z.string(),\n public_logs: z.boolean(),\n public_sysinfo: z.boolean(),\n runner: z.string().optional(),\n salt: z.string().nullable().optional(),\n tproxy_enabled: z.boolean(),\n version: z.string().optional()\n});\n\n// Configuration Schema\nexport const configurationSchema = z.object({\n name: z.string(),\n image: z.string(),\n compose_file: composeFileSchema,\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n ports: z.array(z.any())\n});\n\n// Hosted Schema\nexport const hostedSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.string(),\n uptime: z.string(),\n app_url: z.string(),\n app_id: z.string(),\n instance_id: z.string(),\n configuration: configurationSchema,\n exited_at: z.string(),\n boot_progress: z.string(),\n boot_error: z.string(),\n shutdown_progress: z.string(),\n image_version: z.string()\n});\n\n// Managed User Schema\nexport const managedUserSchema = z.object({\n id: z.number(),\n username: z.string()\n});\n\n// Node Schema\nexport const nodeSchema = z.object({\n id: z.number(),\n name: z.string()\n});\n\n// CVM Instance Schema\nexport const cvmInstanceSchema = z.object({\n hosted: hostedSchema,\n name: z.string(),\n managed_user: managedUserSchema,\n node: nodeSchema,\n listed: z.boolean(),\n status: z.string(),\n in_progress: z.boolean(),\n dapp_dashboard_url: z.string().nullable(),\n syslog_endpoint: z.string(),\n allow_upgrade: z.boolean()\n});\n\n// POST request CVM Response Schema\nexport const postCvmResponseSchema = z.object({\n id: z.number(),\n name: z.string(),\n status: z.string(),\n teepod_id: z.number().nullable(),\n teepod: z.object({\n id: z.number(),\n name: z.string()\n }).nullable(),\n user_id: z.number(),\n app_id: z.string(),\n vm_uuid: z.string().nullable(),\n instance_id: z.string().nullable(),\n app_url: z.string().nullable(),\n base_image: z.string(),\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n manifest_version: z.number(),\n version: z.string(),\n runner: z.string(),\n docker_compose_file: z.string(),\n features: z.array(z.string()).nullable(),\n created_at: z.string(),\n encrypted_env_pubkey: z.string()\n});\n\n// Get Pubkey From CVM Response Schema\nexport const getPubkeyFromCvmResponseSchema = z.object({\n app_env_encrypt_pubkey: z.string(),\n app_id_salt: z.string()\n});\n\n// Get CVM By App ID Response Schema\nexport const getCvmByAppIdResponseSchema = z.object({\n id: z.number(),\n teepod_id: z.number().nullable(),\n teepod: z.object({\n id: z.number(),\n name: z.string()\n }).nullable(),\n name: z.string(),\n status: z.string(),\n in_progress: z.boolean(),\n app_id: z.string(),\n vm_uuid: z.string(),\n instance_id: z.string(),\n vcpu: z.number(),\n memory: z.number(),\n disk_size: z.number(),\n base_image: z.string(),\n encrypted_env_pubkey: z.string(),\n listed: z.boolean(),\n project_id: z.string(),\n project_type: z.string().nullable()\n});\n\n// Get User Info Response Schema\nexport const getUserInfoResponseSchema = z.object({\n username: z.string(),\n email: z.string(),\n credits: zodDecimal.create({ coerce: true }),\n granted_credits: zodDecimal.create({ coerce: true }),\n role: z.string(),\n avatar: z.string(),\n flag_reset_password: z.boolean(),\n team_name: z.string(),\n team_tier: z.string(),\n trial_ended_at: z.string().nullable()\n});\n\n// Get CVMs By User ID Response Schema\nexport const getCvmsByUserIdResponseSchema = z.array(cvmInstanceSchema);\n\n// Upgrade CVM Response Schema\nexport const upgradeCvmResponseSchema = z.object({\n detail: z.string()\n});\n\n// Encrypted Env Item Schema\nexport const encryptedEnvItemSchema = z.object({\n key: z.string(),\n value: z.string()\n});\n\n// Image Schema\nexport const imageSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n version: z.array(z.number()).optional(),\n is_dev: z.boolean().optional(),\n rootfs_hash: z.string().optional(),\n shared_ro: z.boolean().optional(),\n cmdline: z.string().optional(),\n kernel: z.string().optional(),\n initrd: z.string().optional(),\n hda: z.string().nullable().optional(),\n rootfs: z.string().optional(),\n bios: z.string().optional()\n});\n\n// TEEPod Schema with extended properties\nexport const teepodSchema = z.object({\n teepod_id: z.number().nullable(),\n name: z.string(),\n listed: z.boolean(),\n resource_score: z.number(),\n remaining_vcpu: z.number(),\n remaining_memory: z.number(),\n remaining_cvm_slots: z.number(),\n images: z.array(imageSchema).optional()\n});\n\n// Capacity Schema\nexport const capacitySchema = z.object({\n max_instances: z.number().nullable(),\n max_vcpu: z.number().nullable(),\n max_memory: z.number().nullable(),\n max_disk: z.number().nullable()\n});\n\n// TeepodResponse Schema\nexport const teepodResponseSchema = z.object({\n tier: z.string(),\n capacity: capacitySchema,\n nodes: z.array(teepodSchema)\n});\n\n// Get CVM Network Response Schema\nexport const getCvmNetworkResponseSchema = z.object({\n is_online: z.boolean(),\n is_public: z.boolean(),\n error: z.string().nullable(),\n internal_ip: z.string(),\n latest_handshake: z.string(),\n public_urls: z.array(z.object({\n app: z.string(),\n instance: z.string()\n })),\n});\n\n// Type exports\nexport type DockerConfig = z.infer<typeof dockerConfigSchema>;\nexport type ComposeFile = z.infer<typeof composeFileSchema>;\nexport type Configuration = z.infer<typeof configurationSchema>;\nexport type Hosted = z.infer<typeof hostedSchema>;\nexport type ManagedUser = z.infer<typeof managedUserSchema>;\nexport type Node = z.infer<typeof nodeSchema>;\nexport type CvmInstance = z.infer<typeof cvmInstanceSchema>;\nexport type PostCvmResponse = z.infer<typeof postCvmResponseSchema>;\nexport type GetPubkeyFromCvmResponse = z.infer<typeof getPubkeyFromCvmResponseSchema>;\nexport type GetCvmByAppIdResponse = z.infer<typeof getCvmByAppIdResponseSchema>;\nexport type GetUserInfoResponse = z.infer<typeof getUserInfoResponseSchema>;\nexport type GetCvmsByUserIdResponse = z.infer<typeof getCvmsByUserIdResponseSchema>;\nexport type UpgradeCvmResponse = z.infer<typeof upgradeCvmResponseSchema>;\nexport type EncryptedEnvItem = z.infer<typeof encryptedEnvItemSchema>;\nexport type TEEPod = z.infer<typeof teepodSchema>;\nexport type Image = z.infer<typeof imageSchema>;\nexport type Capacity = z.infer<typeof capacitySchema>;\nexport type TeepodResponse = z.infer<typeof teepodResponseSchema>;\nexport type CvmAttestationResponse = z.infer<typeof cvmAttestationResponseSchema>;\nexport type GetCvmNetworkResponse = z.infer<typeof getCvmNetworkResponseSchema>;\n/**\n * Certificate naming information\n */\nexport interface CertificateNameInfo {\n common_name: string | null;\n organization: string | null;\n country: string | null;\n state?: string | null;\n locality?: string | null;\n}\n\n/**\n * Certificate data structure\n */\nexport interface CertificateInfo {\n subject: CertificateNameInfo;\n issuer: CertificateNameInfo;\n serial_number: string;\n not_before: string;\n not_after: string;\n version: string;\n fingerprint: string;\n signature_algorithm: string;\n sans: string | null;\n is_ca: boolean;\n position_in_chain: number;\n quote: string | null;\n}\n\n/**\n * Event log entry\n */\nexport interface TCBEventLogEntry {\n imr: number;\n event_type: number;\n digest: string;\n event: string;\n event_payload: string;\n}\n\n/**\n * Trusted Computing Base (TCB) information\n */\nexport interface TCBInfo {\n mrtd: string;\n rootfs_hash: string;\n rtmr0: string;\n rtmr1: string;\n rtmr2: string;\n rtmr3: string;\n event_log: TCBEventLogEntry[];\n}\n\nexport const cvmAttestationResponseSchema = z.object({\n is_online: z.boolean(),\n is_public: z.boolean(),\n error: z.string().nullable(),\n app_certificates: z.array(z.object({\n subject: z.object({\n common_name: z.string().nullable(),\n organization: z.string().nullable(),\n country: z.string().nullable(),\n state: z.string().nullable().optional(),\n locality: z.string().nullable().optional()\n }),\n issuer: z.object({\n common_name: z.string().nullable(),\n organization: z.string().nullable(),\n country: z.string().nullable()\n }),\n serial_number: z.string(),\n not_before: z.string(),\n not_after: z.string(),\n version: z.string(),\n fingerprint: z.string(),\n signature_algorithm: z.string(),\n sans: z.string().nullable(),\n is_ca: z.boolean(),\n position_in_chain: z.number(),\n quote: z.string().nullable()\n })).nullable(),\n tcb_info: z.object({\n mrtd: z.string(),\n rootfs_hash: z.string(),\n rtmr0: z.string(),\n rtmr1: z.string(),\n rtmr2: z.string(),\n rtmr3: z.string(),\n event_log: z.array(z.object({\n imr: z.number(),\n event_type: z.number(),\n digest: z.string(),\n event: z.string(),\n event_payload: z.string()\n }))\n }).nullable(),\n compose_file: z.string().nullable()\n});","import {\n INVALID,\n ParseContext,\n ParseInput,\n ParseReturnType,\n ParseStatus,\n RawCreateParams,\n ZodIssueCode,\n ZodParsedType,\n ZodType,\n ZodTypeDef,\n addIssueToContext,\n z,\n} from 'zod';\n\nexport type ZodDecimalCheck =\n | { kind: 'precision'; value: number; message?: string }\n | { kind: 'wholeNumber'; value: number; message?: string }\n | { kind: 'min'; value: number; inclusive: boolean; message?: string }\n | { kind: 'max'; value: number; inclusive: boolean; message?: string }\n | { kind: 'finite'; message?: string };\n\nconst zodDecimalKind = 'ZodDecimal';\n\nexport interface ZodDecimalDef extends ZodTypeDef {\n checks: ZodDecimalCheck[];\n typeName: typeof zodDecimalKind;\n coerce: boolean;\n}\n\nconst precisionRegex = /(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ZodDecimal extends ZodType<number, ZodDecimalDef, any> {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n _parse(input: ParseInput): ParseReturnType<number> {\n // detect decimal js object\n if (input.data !== null && typeof input.data === 'object' && 'toNumber' in input.data) {\n input.data = input.data.toNumber();\n }\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.number,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n\n let ctx: undefined | ParseContext = undefined;\n const status = new ParseStatus();\n\n for (const check of this._def.checks) {\n if (check.kind === 'precision') {\n const parts = input.data.toString().match(precisionRegex);\n const decimals = Math.max(\n (parts[1] ? parts[1].length : 0) - (parts[2] ? parseInt(parts[2], 10) : 0),\n 0\n );\n if (decimals > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.custom,\n message: check.message,\n params: {\n precision: check.value,\n },\n });\n status.dirty();\n }\n } else if (check.kind === 'wholeNumber') {\n const wholeNumber = input.data.toString().split('.')[0];\n const tooLong = wholeNumber.length > check.value;\n\n if (tooLong) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.custom,\n message: check.message,\n params: {\n wholeNumber: check.value,\n },\n });\n status.dirty();\n }\n } else if (check.kind === 'min') {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: 'number',\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n } else if (check.kind === 'max') {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: 'number',\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n } else if (check.kind === 'finite') {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n }\n\n return { status: status.value, value: input.data };\n }\n\n static create = (params?: RawCreateParams & { coerce?: true }): ZodDecimal => {\n return new ZodDecimal({\n checks: [],\n typeName: zodDecimalKind,\n coerce: params?.coerce ?? false,\n });\n };\n\n protected setLimit(\n kind: 'min' | 'max',\n value: number,\n inclusive: boolean,\n message?: string\n ): ZodDecimal {\n return new ZodDecimal({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message,\n },\n ],\n });\n }\n\n _addCheck(check: ZodDecimalCheck): ZodDecimal {\n return new ZodDecimal({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n\n lte(value: number, message?: string): ZodDecimal {\n return this.setLimit('max', value, true, message);\n }\n\n lt(value: number, message?: string): ZodDecimal {\n return this.setLimit('max', value, false, message);\n }\n max = this.lte;\n\n gt(value: number, message?: string): ZodDecimal {\n return this.setLimit('min', value, false, message);\n }\n gte(value: number, message?: string): ZodDecimal {\n return this.setLimit('min', value, true, message);\n }\n\n min = this.gte;\n\n precision(value: number, message?: string): ZodDecimal {\n return this._addCheck({\n kind: 'precision',\n value,\n message,\n });\n }\n wholeNumber(value: number, message?: string): ZodDecimal {\n return this._addCheck({\n kind: 'wholeNumber',\n value,\n message,\n });\n }\n\n get minValue() {\n let min: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'min') {\n if (min === null || ch.value > min) min = ch.value;\n }\n }\n return min;\n }\n\n get maxValue() {\n let max: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'max') {\n if (max === null || ch.value < max) max = ch.value;\n }\n }\n return max;\n }\n\n positive(message?: string) {\n return this._addCheck({\n kind: 'min',\n value: 0,\n inclusive: false,\n message,\n });\n }\n\n negative(message?: string) {\n return this._addCheck({\n kind: 'max',\n value: 0,\n inclusive: false,\n message,\n });\n }\n\n nonpositive(message?: string) {\n return this._addCheck({\n kind: 'max',\n value: 0,\n inclusive: true,\n message,\n });\n }\n\n nonnegative(message?: string) {\n return this._addCheck({\n kind: 'min',\n value: 0,\n inclusive: true,\n message,\n });\n }\n\n finite(message?: string) {\n return this._addCheck({\n kind: 'finite',\n message,\n });\n }\n\n safe(message?: string) {\n return this._addCheck({\n kind: 'min',\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message,\n })._addCheck({\n kind: 'max',\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message,\n });\n }\n\n get isFinite() {\n let max: number | null = null;\n let min: number | null = null;\n for (const ch of this._def.checks) {\n if (ch.kind === 'finite') {\n return true;\n } else if (ch.kind === 'min') {\n if (min === null || ch.value > min) min = ch.value;\n } else if (ch.kind === 'max') {\n if (max === null || ch.value < max) max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\n\n// Docker Compose Template Schema\nexport const ComposeTemplateSchema = z.object({\n template: z.string().min(1, \"Template cannot be empty\")\n});\n\nexport type ComposeTemplate = z.infer<typeof ComposeTemplateSchema>;","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '../utils/constants';\nimport { GetUserInfoResponse, getUserInfoResponseSchema } from './types';\nimport { logger } from '../utils/logger';\n\n// Helper function to safely stringify objects that might contain cyclic references\nfunction safeStringify(obj: any): string {\n try {\n return JSON.stringify(obj);\n } catch (error) {\n if (error instanceof Error && error.message.includes('cyclic')) {\n return '[Cyclic Object]';\n }\n return String(obj);\n }\n}\n\n/**\n * Get user information\n * @returns User information\n */\nexport async function getUserInfo(): Promise<GetUserInfoResponse> {\n try {\n logger.debug(`Fetching user info from ${API_ENDPOINTS.USER_INFO}`);\n const response = await apiClient.get<any>(API_ENDPOINTS.USER_INFO);\n logger.debug(`Received response: ${safeStringify(response)}`);\n \n // Try to parse the response with the schema\n try {\n return getUserInfoResponseSchema.parse(response);\n } catch (parseError) {\n logger.error(`Failed to parse user info response: ${parseError}`);\n logger.debug(`Response structure: ${safeStringify(response)}`);\n throw parseError;\n }\n } catch (error) {\n logger.error(`Failed to get user info: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error(`Failed to get user info: ${error instanceof Error ? error.message : String(error)}`);\n }\n}","import { Command } from 'commander';\nimport { removeApiKey } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\n\nexport const logoutCommand = new Command()\n .name('logout')\n .description('Remove the stored API key')\n .action(async () => {\n try {\n await removeApiKey();\n logger.success('API key removed successfully');\n } catch (error) {\n logger.error(`Failed to remove API key: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { getApiKey } from '@/src/utils/credentials';\nimport { getUserInfo } from '@/src/api/auth';\nimport { logger } from '@/src/utils/logger';\n\nexport const statusCommand = new Command()\n .name('status')\n .description('Check authentication status')\n .option('-j, --json', 'Output in JSON format')\n .option('-d, --debug', 'Enable debug output')\n .action(async (options) => {\n try {\n // Enable debug mode if requested\n if (options.debug) {\n process.env.DEBUG = 'true';\n }\n \n const apiKey = await getApiKey();\n \n if (!apiKey) {\n logger.warn('Not authenticated. Please set an API key with \"phala auth login\"');\n return;\n }\n \n logger.debug(`Using API key: ${apiKey.substring(0, 5)}...`);\n const spinner = logger.startSpinner('Checking authentication status');\n \n try {\n const userInfo = await getUserInfo();\n spinner.stop(true);\n \n if (options.json) {\n console.log(JSON.stringify(userInfo, null, 2));\n return;\n }\n \n logger.break();\n logger.success(`Authenticated as ${userInfo.username}`);\n \n // Create a simple object\n const tableData = {\n 'Username': userInfo.username,\n 'Email': userInfo.email,\n 'Role': userInfo.role,\n 'Team': `${userInfo.team_name} (${userInfo.team_tier})`,\n 'Credits': `${userInfo.credits + userInfo.granted_credits}`\n };\n \n if (userInfo.trial_ended_at) {\n tableData['Trial Ended At'] = userInfo.trial_ended_at;\n }\n \n // Display the table\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n } catch (error) {\n spinner.stop(false);\n logger.error('Authentication failed. Your API key may be invalid or expired.');\n logger.info('Please set a new API key with \"phala auth login\"');\n \n if (options.debug) {\n logger.debug(`Error details: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n } catch (error) {\n logger.error(`Failed to check authentication status: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { loginCommand } from './login';\nimport { buildCommand } from './build';\nimport { pushCommand } from './push';\nimport { generateCommand } from './generate';\n\nexport const dockerCommands = new Command()\n .name('docker')\n .description('Login to Docker Hub and manage Docker images')\n .addCommand(loginCommand)\n .addCommand(buildCommand)\n .addCommand(pushCommand)\n .addCommand(generateCommand);\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { saveDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport prompts from 'prompts';\n\nexport const loginCommand = new Command()\n .name('login')\n .description('Login to Docker Hub')\n .option('-u, --username <username>', 'Docker Hub username')\n .option('-p, --password <password>', 'Docker Hub password')\n .option('-r, --registry <registry>', 'Docker registry URL')\n .action(async (options) => {\n try {\n let username = options.username;\n let password = options.password;\n const registry = options.registry;\n \n // If no username is provided, prompt for it\n if (!username) {\n logger.info('First we need your Docker Hub username to check if you are already logged in.');\n\n const response = await prompts({\n type: 'text',\n name: 'username',\n message: 'Enter your Docker Hub username:',\n validate: value => value.length > 0 ? true : 'Username cannot be empty'\n });\n \n if (!response.username) {\n logger.error('Username is required');\n process.exit(1);\n }\n \n username = response.username;\n }\n\n // Check if Docker is already logged in\n const dockerService = new DockerService('', username, registry);\n const loggedIn = await dockerService.login(username);\n if (loggedIn) {\n logger.success(`${username} is logged in to Docker Hub`);\n // Save credentials\n await saveDockerCredentials({\n username,\n registry: registry || null,\n });\n return;\n }\n \n // If no password is provided, prompt for it\n if (!password) {\n const response = await prompts({\n type: 'password',\n name: 'password',\n message: 'Enter your Docker Hub password:',\n validate: value => value.length > 0 ? true : 'Password cannot be empty'\n });\n \n if (!response.password) {\n logger.error('Password is required');\n process.exit(1);\n }\n \n password = response.password;\n }\n \n // Login to Docker Hub\n const success = await dockerService.login(username, password, registry);\n \n if (!success) {\n logger.error('Failed to login to Docker Hub');\n process.exit(1);\n }\n \n // Save credentials\n await saveDockerCredentials({\n username,\n registry: registry || null\n });\n \n logger.success('Logged in to Docker Hub successfully');\n } catch (error) {\n logger.error(`Failed to login to Docker Hub: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from './logger';\nimport { DOCKER_COMPOSE_BASIC_TEMPLATE, DOCKER_COMPOSE_ELIZA_V2_TEMPLATE } from './constants';\nimport { getDockerCredentials } from './credentials';\nimport Handlebars from 'handlebars';\nimport { exec, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport os from 'node:os';\nimport { validateFileExists } from './prompts';\nimport { ComposeTemplateSchema } from './types';\nimport { deleteSimulatorEndpointEnv, setSimulatorEndpointEnv } from './simulator';\nconst execAsync = promisify(exec);\n\nconst LOGS_DIR = '.phala-cloud/logs';\nconst COMPOSE_FILES_DIR = '.phala-cloud/compose';\nconst MAX_CONSOLE_LINES = 10;\n\nexport class DockerService {\n private username: string;\n private image: string;\n private registry: string;\n\n constructor(image: string, username?: string, registry?: string) {\n this.image = image;\n this.username = username || '';\n this.registry = registry || '';\n }\n\n private ensureLogsDir(): void {\n const logsPath = path.resolve(LOGS_DIR);\n if (!fs.existsSync(logsPath)) {\n fs.mkdirSync(logsPath, { recursive: true });\n }\n }\n\n private getLogFilePath(operation: string, image?: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return path.resolve(LOGS_DIR, `${image || this.image}-${operation}-${timestamp}.log`);\n }\n\n private getSystemArchitecture(): string {\n const arch = os.arch();\n switch (arch) {\n case 'arm':\n case 'arm64':\n return 'arm64';\n case 'x64':\n return 'amd64';\n default:\n return arch;\n }\n }\n\n private spawnProcess(command: string, args: string[], operation: string, image?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args);\n // Ensure logs directory exists before creating write stream\n this.ensureLogsDir();\n\n const logFile = this.getLogFilePath(operation, image);\n\n const logStream = fs.createWriteStream(logFile, { flags: 'a' });\n const consoleBuffer: string[] = [];\n\n const processOutput = (data: Buffer, isError = false) => {\n const lines = data.toString().split('\\n');\n\n // Write to log file\n logStream.write(data);\n\n // Update console buffer\n for (const line of lines) {\n if (line.trim()) {\n consoleBuffer.push(line);\n // Keep only the last MAX_CONSOLE_LINES lines\n if (consoleBuffer.length > MAX_CONSOLE_LINES) {\n consoleBuffer.shift();\n }\n\n // Clear console and print the buffer\n console.clear();\n console.log(`Latest ${MAX_CONSOLE_LINES} lines (full log at ${logFile}):`);\n console.log('-'.repeat(50));\n for (const bufferedLine of consoleBuffer) {\n if (isError) {\n console.error(bufferedLine);\n } else {\n console.log(bufferedLine);\n }\n }\n }\n }\n };\n\n proc.stdout.on('data', (data) => processOutput(data));\n proc.stderr.on('data', (data) => processOutput(data, true));\n\n proc.on('close', (code) => {\n logStream.end();\n if (code === 0) {\n console.log(`\\nOperation completed. Full log available at: ${logFile}`);\n resolve();\n } else {\n reject(new Error(`Process exited with code ${code}. Check log file: ${logFile}`));\n }\n });\n\n proc.on('error', (err) => {\n logStream.end();\n reject(err);\n });\n });\n }\n\n /**\n * Set Docker credentials\n * @param username Docker username\n * @param registry Docker registry\n */\n setCredentials(username: string, registry?: string): void {\n this.username = username;\n if (registry) {\n this.registry = registry;\n }\n }\n\n /**\n * Build a Docker image\n * @param dockerfile Path to Dockerfile\n * @param tag Tag for the image\n * @returns Success status\n */\n async buildImage(dockerfile: string, tag: string): Promise<boolean> {\n try {\n const arch = this.getSystemArchitecture();\n const fullImageName = `${this.username}/${this.image}:${tag}`;\n\n const spinner = logger.startSpinner(`Building Docker image ${this.username}/${this.image}:${tag}`);\n\n // Ensure the Dockerfile exists\n validateFileExists(dockerfile);\n\n const buildArgs = ['build', '-t', fullImageName, '-f', dockerfile];\n\n if (arch === 'arm64') {\n console.log('Detected arm64 architecture, using --platform linux/amd64');\n buildArgs.push('--platform', 'linux/amd64');\n }\n\n // Build the image\n buildArgs.push('.');\n\n await this.spawnProcess('docker', buildArgs, 'build', this.image);\n\n spinner.stop(true, `Docker image ${fullImageName} built successfully`);\n return true;\n } catch (error) {\n logger.error(`Failed to build Docker image: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Push a Docker image to Docker Hub\n * @param imageName Full image name (e.g. username/image:tag)\n * @returns Success status\n */\n async pushImage(imageName: string): Promise<boolean> {\n try {\n const spinner = logger.startSpinner(`Pushing Docker image ${imageName} to Docker Hub`);\n\n // Check if user is logged in\n const credentials = await getDockerCredentials();\n if (!credentials) {\n spinner.stop(false);\n throw new Error('Docker credentials not found. Please log in first with \"phala docker login\"');\n }\n\n const fullImageName = imageName;\n console.log(`Pushing image ${fullImageName} to Docker Hub...`);\n\n await this.spawnProcess('docker', ['push', fullImageName], 'push', imageName.replace(/.*\\/+(\\w+):.*$/g, '$1'));\n\n spinner.stop(true, `Docker image ${fullImageName} pushed successfully`);\n return true;\n } catch (error) {\n logger.error(`Failed to push Docker image: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n\n /**\n * Login to Docker Hub\n * @param username Docker username\n * @param password Docker password\n * @param registry Docker registry\n * @returns Success status\n */\n async login(username: string, password?: string, registry?: string): Promise<boolean> {\n try {\n const spinner = logger.startSpinner(`Logging in to Docker Hub as ${username}`);\n\n // Check if already logged in\n const loggedIn = await this.checkLogin();\n if (loggedIn) {\n spinner.stop(true, 'Already logged in to Docker Hub');\n this.setCredentials(username, registry);\n return true;\n }\n\n // Verify password was provided\n if (!password) {\n spinner.stop(false);\n throw new Error('Password is required for Docker login');\n }\n\n // Login to Docker with timeout protection\n try {\n const loginProcess = execa('docker', [\n 'login',\n ...(registry ? [registry] : []),\n '-u',\n username,\n '--password-stdin'\n ], {\n input: password,\n timeout: 10000 // 10 second timeout\n });\n\n await loginProcess;\n } catch (loginError) {\n if (loginError.timedOut) {\n spinner.stop(false);\n throw new Error('Docker login timed out. Please check your credentials and try again.');\n }\n throw loginError;\n }\n\n spinner.stop(true, 'Logged in to Docker Hub successfully');\n this.setCredentials(username, registry);\n return true;\n } catch (error) {\n logger.error(`Failed to login to Docker Hub: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Check if Docker is logged in\n * @returns Success status\n */\n async checkLogin(): Promise<boolean> {\n try {\n // Instead of checking via \"docker login\" which is interactive,\n // check if the Docker config.json file exists and contains auth data\n const homeDir = os.homedir();\n const dockerConfigPath = path.join(homeDir, '.docker', 'config.json');\n \n if (!fs.existsSync(dockerConfigPath)) {\n return false;\n }\n \n // Read the docker config file\n const dockerConfig = JSON.parse(fs.readFileSync(dockerConfigPath, 'utf-8'));\n \n // Check if the config has auths data\n return !!(dockerConfig?.auths && Object.keys(dockerConfig.auths).length > 0);\n } catch (error) {\n logger.debug(`Docker login check failed: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Build a Docker Compose file\n * @param imageName Name of the image\n * @param envFile Optional path to environment file\n * @param version Version of the template to use\n * @returns Path to the generated Docker Compose file\n */\n async buildComposeFile(imageName: string, envFile?: string, templateType?: string): Promise<string> {\n if (!this.username) {\n throw new Error('Docker Hub username is required for building compose file');\n }\n\n const template = (templateType === 'eliza') ? DOCKER_COMPOSE_ELIZA_V2_TEMPLATE : DOCKER_COMPOSE_BASIC_TEMPLATE;\n\n // Validate template structure\n const validatedTemplate = ComposeTemplateSchema.parse({ template });\n\n // Ensure compose files directory exists\n const composePath = path.resolve(COMPOSE_FILES_DIR);\n \n // Create directory if it doesn't exist\n if (!fs.existsSync(composePath)) {\n logger.info(`Creating directory: ${composePath}`);\n fs.mkdirSync(composePath, { recursive: true });\n }\n\n let envVars: string[] = [];\n \n // Only parse env file if it's provided\n if (envFile) {\n // Parse env file to get variable names\n const envContent = fs.readFileSync(envFile, 'utf-8');\n envVars = envContent\n .split('\\n')\n .filter(line => line && !line.startsWith('#'))\n .map(line => {\n // Remove inline comments\n const commentIndex = line.indexOf('#');\n if (commentIndex > 0) {\n line = line.substring(0, commentIndex).trim();\n }\n return line.trim();\n })\n .filter(line => line.includes('='))\n .map(line => {\n const [key, value] = line.split('=', 2);\n const trimmedKey = key.trim();\n const trimmedValue = value ? value.trim() : '';\n\n // Skip empty values\n if (trimmedValue === '') {\n return null;\n }\n\n // Keep the original key without any transformation\n return `${trimmedKey}=${trimmedKey}`; // Create KEY=KEY format\n })\n .filter(Boolean as unknown as ((value: string | null) => value is string)); // Remove null entries\n }\n\n // Create full image name with username\n const fullImageName = imageName;\n\n // Compile template with data\n const compiledTemplate = Handlebars.compile(validatedTemplate.template, { noEscape: true });\n const composeContent = compiledTemplate({\n imageName: fullImageName,\n envVars: envVars.map(env => env.replace(/=.*/, `=\\${${env.split('=')[0]}}`))\n });\n\n // Write the docker-compose file with standardized name in the compose directory\n const composeFile = path.join(\n composePath,\n `${imageName.replace(/.*\\/+(\\w+):.*$/g, \"$1\")}-tee-compose.yaml`,\n );\n fs.writeFileSync(composeFile, composeContent);\n\n logger.success(`Backup of docker compose file created at: ${composeFile}`);\n return composeFile;\n }\n\n /**\n * Run a Docker Compose file locally\n * @param composePath Path to Docker Compose file\n * @param envFile Path to environment file\n * @returns Success status\n */\n async runComposeLocally(composePath: string, envFile?: string): Promise<boolean> {\n try {\n // TODO: Update log when optimized simulator is implemented\n const spinner = logger.startSpinner(`Running Docker Compose file at ${composePath}`);\n\n // Ensure the Docker Compose file exists\n validateFileExists(composePath);\n\n // Build the command arguments\n const composeArgs = [\n '-f',\n composePath,\n 'up',\n '-d'\n ];\n\n // Only add env-file if it's provided\n if (envFile) {\n // Ensure the environment file exists\n validateFileExists(envFile);\n composeArgs.splice(2, 0, '--env-file', envFile);\n }\n\n // Run the Docker Compose file\n await execAsync(`docker compose ${composeArgs.join(' ')}`);\n\n spinner.stop(true, 'Docker Compose file running successfully');\n return true;\n } catch (error) {\n logger.error(`Failed to run Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Run the TEE simulator\n * @param image Simulator image\n * @returns Success status\n */\n async runSimulator(image: string, port: string): Promise<boolean> {\n try {\n logger.info(`Running TEE simulator with image ${image}`);\n\n logger.info('Pulling latest simulator image...');\n await execAsync(`docker pull ${image}`);\n\n logger.info('Starting simulator in background...');\n const { stdout } = await execAsync(`docker run -d --name tee-simulator --rm -p ${port}:${port} ${image}`);\n const containerId = stdout.trim();\n\n logger.success(`TEE simulator running successfully. Container ID: ${containerId}`);\n logger.break();\n logger.break();\n logger.info('Useful commands:');\n logger.info(`- View logs: docker logs -f ${containerId}`);\n logger.info(`- Stop simulator: docker stop ${containerId}`);\n\n setSimulatorEndpointEnv(`http://localhost:${port}`);\n \n return true;\n } catch (error) {\n logger.error(`Failed to run TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * Stop the TEE simulator\n * @returns Success status\n */\n async stopSimulator(): Promise<boolean> {\n try {\n const spinner = logger.startSpinner('Stopping TEE simulator...');\n\n // Stop the simulator\n await execAsync('docker stop tee-simulator');\n await deleteSimulatorEndpointEnv();\n\n spinner.stop(true, 'TEE simulator stopped successfully');\n return true;\n } catch (error) {\n logger.error(`Failed to stop TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n return false;\n }\n }\n\n /**\n * List local Docker images and their tags\n * @returns Array of objects with image name and tag\n */\n static async listLocalImages(): Promise<Array<{ imageName: string}>> {\n try {\n // Query Docker for local images in format that outputs repository and tag\n const { stdout } = await execAsync('docker images --format \"{{.Repository}}:{{.Tag}}\"');\n const credentials = await getDockerCredentials();\n const username = credentials?.username;\n // Parse the output and filter out any <none> tags or images\n const imageList = stdout.split('\\n')\n .filter(line => line && !line.includes('<none>'))\n .filter(line => line.includes(`${username}/`))\n .map(line => {\n const imageName = line;\n return { imageName };\n });\n\n return imageList;\n } catch (error) {\n logger.error(`Failed to list local Docker images: ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n }\n}\n\n","import inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from './logger';\n\n/**\n * Validates that a file exists at the given path\n * @param filePath Path to the file to validate\n * @param basePath Optional base path to resolve relative paths against (defaults to process.cwd())\n * @returns True if the file exists, throws an error if not\n * @throws Error if the file does not exist\n */\nexport function validateFileExists(\n filePath: string,\n basePath: string = process.cwd()\n): boolean {\n const resolvedPath = path.resolve(basePath, filePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`File not found at ${resolvedPath}`);\n }\n return true;\n}\n\n/**\n * Prompts the user for a file path and validates that the file exists\n * @param message The prompt message to display\n * @param defaultValue The default value for the prompt\n * @param name The name of the prompt (used as property name in the returned object)\n * @param basePath Optional base path to resolve relative paths against (defaults to process.cwd())\n * @returns The validated file path\n */\nexport async function promptForFile(\n message: string,\n defaultValue: string,\n name = 'file',\n basePath: string = process.cwd()\n): Promise<string> {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name,\n message,\n default: defaultValue,\n validate: (input) => {\n const filePath = path.resolve(basePath, input);\n if (!fs.existsSync(filePath)) {\n return `File not found at ${filePath}`;\n }\n return true;\n }\n }\n ]);\n\n return response[name];\n}\n\nexport function detectFileInCurrentDir(\n possibleFiles: string[],\n logMessage?: string\n): string | undefined {\n for (const file of possibleFiles) {\n const filePath = path.join(process.cwd(), file);\n if (fs.existsSync(filePath)) {\n if (logMessage) {\n logger.info(logMessage.replace('{path}', filePath));\n } else {\n logger.info(`File detected: ${filePath}`);\n }\n return file;\n }\n }\n return undefined;\n}","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { execSync, spawn, type StdioOptions } from 'node:child_process';\nimport * as net from 'node:net';\nimport { logger } from './logger';\n\n// Configuration for simulator\nconst SIMULATOR_CONFIG = {\n version: '0.1.4',\n baseUrl: 'https://github.com/Leechael/tappd-simulator/releases/download/v0.1.4',\n installDir: path.join(os.homedir(), '.phala-cloud', 'tappd-simulator'),\n // Default log file path\n defaultLogPath: path.join(os.homedir(), '.phala-cloud', 'logs', 'tappd-simulator.log'),\n platforms: {\n darwin: {\n filename: 'tappd-simulator-0.1.4-aarch64-apple-darwin.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-aarch64-apple-darwin',\n socketArg: 'unix:/tmp/tappd.sock'\n },\n linux: {\n filename: 'tappd-simulator-0.1.4-x86_64-linux-musl.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-x86_64-linux-musl',\n socketArg: 'unix:/tmp/tappd.sock'\n },\n win32: {\n filename: 'tappd-simulator-0.1.4-x86_64-pc-windows-msvc.tgz',\n extractedFolder: 'tappd-simulator-0.1.4-x86_64-pc-windows-msvc',\n socketArg: '127.0.0.1:8090'\n }\n }\n};\n\n/**\n * Check if the simulator is already installed\n * @returns boolean indicating if simulator is installed\n */\nexport function isSimulatorInstalled(): boolean {\n try {\n // Check if the main installation directory exists\n if (!fs.existsSync(SIMULATOR_CONFIG.installDir)) {\n return false;\n }\n\n // Get platform-specific folder name\n const platform = os.platform() as 'darwin' | 'linux' | 'win32';\n if (!SIMULATOR_CONFIG.platforms[platform]) {\n throw new Error(`Unsupported platform: ${platform}`);\n }\n\n const extractedFolderPath = path.join(\n SIMULATOR_CONFIG.installDir,\n SIMULATOR_CONFIG.platforms[platform].extractedFolder\n );\n\n // Check if the extracted folder exists\n if (!fs.existsSync(extractedFolderPath)) {\n return false;\n }\n\n // Check if the executable exists\n const executableName = platform === 'win32' ? 'tappd-simulator.exe' : 'tappd-simulator';\n const executablePath = path.join(extractedFolderPath, executableName);\n return fs.existsSync(executablePath);\n } catch (error) {\n logger.error('Error checking if simulator is installed:', error);\n return false;\n }\n}\n\n/**\n * Get the current platform\n * @returns The current platform: 'darwin', 'linux', or 'win32'\n * @throws Error if the platform is not supported\n */\nexport function getPlatform(): 'darwin' | 'linux' | 'win32' {\n const platform = os.platform() as 'darwin' | 'linux' | 'win32';\n if (!SIMULATOR_CONFIG.platforms[platform]) {\n throw new Error(`Unsupported platform: ${platform}. Only darwin, linux, and win32 are supported.`);\n }\n return platform;\n}\n\n/**\n * Install the simulator based on the current platform\n * @param progressCallback Optional callback to report progress\n * @returns Promise that resolves when installation is complete\n */\nexport async function installSimulator(\n progressCallback?: (message: string) => void\n): Promise<void> {\n const log = (message: string) => {\n logger.info(message);\n if (progressCallback) progressCallback(message);\n };\n\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n \n // Create installation directory if it doesn't exist\n if (!fs.existsSync(SIMULATOR_CONFIG.installDir)) {\n logger.info(`Creating installation directory at ${SIMULATOR_CONFIG.installDir}`);\n fs.mkdirSync(SIMULATOR_CONFIG.installDir, { recursive: true });\n }\n\n // Change to the installation directory\n process.chdir(SIMULATOR_CONFIG.installDir);\n \n // Download the simulator\n const downloadUrl = `${SIMULATOR_CONFIG.baseUrl}/${platformConfig.filename}`;\n logger.info(`Downloading simulator from ${downloadUrl}`);\n execSync(`wget ${downloadUrl}`, { stdio: 'inherit' });\n \n // Extract the archive\n logger.info(`Extracting ${platformConfig.filename}`);\n execSync(`tar -xvf ${platformConfig.filename}`, { stdio: 'inherit' });\n \n logger.success('Simulator installation completed successfully');\n } catch (error) {\n logger.error('Error installing simulator:', error);\n throw new Error(`Failed to install simulator: ${error}`);\n }\n}\n\n/**\n * Run the simulator\n * @param options Configuration options for running the simulator\n * @returns A child process representing the running simulator\n */\nexport async function runSimulator(options: {\n background?: boolean;\n logToFile?: boolean;\n logFilePath?: string;\n} = {}): Promise<ReturnType<typeof spawn>> {\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n const extractedFolderPath = path.join(\n SIMULATOR_CONFIG.installDir,\n platformConfig.extractedFolder\n );\n \n // Change to the extracted folder directory\n process.chdir(extractedFolderPath);\n \n // Start the simulator\n const executableName = platform === 'win32' ? 'tappd-simulator.exe' : './tappd-simulator';\n \n // Default options\n const runOptions = {\n background: options.background ?? true,\n logToFile: options.logToFile ?? true,\n logFilePath: options.logFilePath ?? SIMULATOR_CONFIG.defaultLogPath\n };\n \n // Create log directory if it doesn't exist\n if (runOptions.logToFile) {\n const logDir = path.dirname(runOptions.logFilePath);\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n logger.info(`Simulator logs will be written to: ${runOptions.logFilePath}`);\n }\n \n logger.info(`Starting simulator with: ${executableName} -l ${platformConfig.socketArg}`);\n \n // Configure stdio based on logging preferences\n let stdio: StdioOptions = 'inherit';\n let outputStream: fs.WriteStream = null;\n \n if (runOptions.logToFile) {\n // Create/open the log file for appending\n outputStream = fs.createWriteStream(runOptions.logFilePath, { flags: 'a' });\n \n // Use the stream for both stdout and stderr\n stdio = ['ignore', outputStream, outputStream];\n }\n \n // Run the simulator\n const simulatorProcess = spawn(executableName, ['-l', platformConfig.socketArg], {\n stdio,\n shell: platform === 'win32', // Use shell on Windows\n detached: runOptions.background // Detach process when running in background\n });\n \n // Write startup entry to log file with timestamp\n if (outputStream) {\n const timestamp = new Date().toISOString();\n outputStream.write(`\\n[${timestamp}] Simulator started\\n`);\n }\n \n // If running in background, unref to allow the parent process to exit\n if (runOptions.background) {\n simulatorProcess.unref();\n logger.success('Simulator is running in the background');\n }\n \n await setSimulatorEndpointEnv();\n return simulatorProcess;\n } catch (error) {\n logger.error('Error running simulator:', error);\n throw new Error(`Failed to run simulator: ${error}`);\n }\n}\n\n/**\n * Ensures the simulator is installed and running\n * @param options Configuration options for running the simulator\n * @returns A promise that resolves to a child process representing the running simulator\n */\nexport async function ensureSimulatorRunning(options: {\n background?: boolean;\n logToFile?: boolean;\n logFilePath?: string;\n} = {}): Promise<ReturnType<typeof spawn>> {\n if (!isSimulatorInstalled()) {\n logger.info('Simulator not installed. Installing now...');\n await installSimulator((message) => logger.info(`Installation progress: ${message}`));\n }\n \n if (await isSimulatorRunning()) {\n logger.info('Simulator is already running');\n return null;\n }\n \n logger.info('Starting simulator...');\n return await runSimulator(options);\n}\n\n/**\n * Check if the simulator is currently running\n * For Unix platforms (Darwin/Linux), checks if the Unix socket exists and is accessible\n * For Windows, tries to connect to the TCP port the simulator should be listening on\n * @returns Promise<boolean> indicating if the simulator is running\n */\nexport async function isSimulatorRunning(): Promise<boolean> {\n try {\n const platform = getPlatform();\n const platformConfig = SIMULATOR_CONFIG.platforms[platform];\n \n if (platform === 'darwin' || platform === 'linux') {\n // For Unix platforms, check if the socket file exists and is accessible\n const socketPath = '/tmp/tappd.sock';\n \n // Check if the socket file exists\n if (!fs.existsSync(socketPath)) {\n return false;\n }\n \n // Try to connect to the socket to verify it's active\n return new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath })\n .on('connect', () => {\n client.end();\n resolve(true);\n })\n .on('error', () => {\n resolve(false);\n });\n \n // Set timeout to avoid hanging if socket exists but nothing is listening\n setTimeout(() => {\n client.end();\n resolve(false);\n }, 1000);\n });\n } \n if (platform === 'win32') {\n // For Windows, try to connect to the TCP port\n const host = '127.0.0.1';\n const port = 8090;\n \n return new Promise<boolean>((resolve) => {\n const client = net.createConnection({ host, port })\n .on('connect', () => {\n client.end();\n resolve(true);\n })\n .on('error', () => {\n resolve(false);\n });\n \n // Set timeout to avoid hanging\n setTimeout(() => {\n client.end();\n resolve(false);\n }, 1000);\n });\n }\n \n return false;\n } catch (error) {\n logger.error('Error checking if simulator is running:', error);\n return false;\n }\n}\n\n/**\n * Stops the simulator if it's running\n * @returns Promise<boolean> indicating if the simulator was successfully stopped\n */\nexport async function stopSimulator(): Promise<boolean> {\n try {\n const platform = getPlatform();\n \n if (!await isSimulatorRunning()) {\n logger.info('Simulator is not running');\n return true;\n }\n \n logger.info('Stopping simulator...');\n \n if (platform === 'win32') {\n // For Windows, find the process listening on port 8080 and kill it\n execSync('for /f \"tokens=5\" %a in (\\'netstat -ano ^| findstr :8080\\') do taskkill /F /PID %a', { stdio: 'inherit' });\n } else {\n // For Unix platforms, find and kill the tappd-simulator process\n execSync('pkill -f tappd-simulator', { stdio: 'inherit' });\n }\n \n // Verify the simulator has stopped\n const stopped = !(await isSimulatorRunning());\n if (stopped) {\n logger.success('Simulator stopped successfully');\n } else {\n logger.error('Failed to stop simulator');\n }\n \n await deleteSimulatorEndpointEnv();\n return stopped;\n } catch (error) {\n logger.error('Error stopping simulator:', error);\n return false;\n }\n}\n\n/**\n * Gets the path to the simulator log file\n * @param customPath Optional custom log file path\n * @returns The path to the log file\n */\nexport function getSimulatorLogPath(customPath?: string): string {\n return customPath ?? SIMULATOR_CONFIG.defaultLogPath;\n}\n\n/**\n * Reads the recent logs from the simulator log file\n * @param options Options for reading logs\n * @returns Recent log content or null if log file doesn't exist\n */\nexport function getSimulatorLogs(options: {\n logFilePath?: string;\n maxLines?: number;\n} = {}): string | null {\n const logFilePath = options.logFilePath ?? SIMULATOR_CONFIG.defaultLogPath;\n const maxLines = options.maxLines ?? 100;\n \n try {\n if (!fs.existsSync(logFilePath)) {\n return null;\n }\n \n // Read the log file\n const logContent = fs.readFileSync(logFilePath, 'utf8');\n \n // Split by lines and get the most recent ones\n const lines = logContent.split('\\n');\n return lines.slice(-maxLines).join('\\n');\n } catch (error) {\n logger.error('Error reading simulator logs:', error);\n return null;\n }\n}\n\n/**\n * Gets the simulator endpoint URL based on the current platform\n * @returns The endpoint URL for the simulator\n */\nexport function getSimulatorEndpoint(): string {\n const platform = getPlatform();\n \n if (platform === 'win32') {\n return 'http://127.0.0.1:8090';\n }\n\n return 'unix:///tmp/tappd.sock';\n}\n\n/**\n * Sets the DSTACK_SIMULATOR_ENDPOINT environment variable based on the current platform\n * @param options Configuration options for setting the environment variable\n * @returns The endpoint URL that was set\n */\nexport async function setSimulatorEndpointEnv(endpoint?: string): Promise<string> {\n try {\n const simulatorEndpoint = getSimulatorEndpoint();\n // Set for the current Node.js process\n const envEndpoint = (endpoint) ? endpoint : simulatorEndpoint;\n await execSync(`export DSTACK_SIMULATOR_ENDPOINT=${envEndpoint}`);\n logger.success(`Setting DSTACK_SIMULATOR_ENDPOINT=${envEndpoint} for current process`);\n \n return endpoint;\n } catch (error) {\n logger.error('Error setting simulator endpoint environment variable:', error);\n throw new Error(`Failed to set simulator endpoint: ${error}`);\n }\n}\n\n/**\n * Deletes the DSTACK_SIMULATOR_ENDPOINT environment variable\n * @returns boolean indicating if deletion was successful\n */\nexport async function deleteSimulatorEndpointEnv(): Promise<boolean> {\n await execSync('unset DSTACK_SIMULATOR_ENDPOIN');\n logger.success('Deleted DSTACK_SIMULATOR_ENDPOINT from current process');\n return true;\n}\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport path from 'node:path';\nimport inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport { promptForFile } from '@/src/utils/prompts';\n\nexport const buildCommand = new Command()\n .name('build')\n .description('Build a Docker image')\n .option('-i, --image <image>', 'Image name')\n .option('-t, --tag <tag>', 'Image tag')\n .option('-f, --file <file>', 'Path to Dockerfile', 'Dockerfile')\n .action(async (options) => {\n try {\n // Get Docker credentials\n const credentials = await getDockerCredentials();\n \n if (!credentials) {\n logger.error('Docker information not found. Please login first with \"phala docker login\"');\n process.exit(1);\n }\n \n // Prompt for image name if not provided\n if (!options.image) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'image',\n message: 'Enter the Docker image name:',\n validate: (input) => {\n if (!input.trim()) {\n return 'Image name is required';\n }\n return true;\n }\n }\n ]);\n \n options.image = response.image;\n }\n\n if (!options.tag) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'tag',\n message: 'Enter the Docker image tag:',\n default: 'latest', // Add random hash later\n validate: (input) => {\n if (!input.trim()) {\n return 'Tag is required';\n }\n return true;\n }\n }\n ]);\n\n options.tag = response.tag;\n }\n\n // Prompt for Dockerfile path if the default doesn't exist\n const defaultPath = path.resolve(process.cwd(), options.file);\n if (!fs.existsSync(defaultPath)) {\n logger.info(`Default Dockerfile not found at ${defaultPath}`);\n \n options.file = await promptForFile(\n 'Enter the path to your Dockerfile:',\n 'Dockerfile',\n 'file'\n );\n }\n \n // Resolve the Dockerfile path\n const dockerfilePath = path.resolve(process.cwd(), options.file);\n \n // Build the image\n const dockerService = new DockerService(options.image, credentials.username, credentials.registry);\n const success = await dockerService.buildImage(dockerfilePath, options.tag);\n \n if (!success) {\n logger.error('Failed to build Docker image');\n process.exit(1);\n }\n \n logger.success(`Docker image ${credentials.username}/${options.image}:${options.tag} built successfully`);\n } catch (error) {\n logger.error(`Failed to build Docker image: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\n\nexport const pushCommand = new Command()\n .name('push')\n .description('Push a Docker image to Docker Hub')\n .option('-i, --image <image>', 'Full image name (e.g. username/image:tag)')\n .action(async (options) => {\n try {\n // Get Docker credentials\n const credentials = await getDockerCredentials();\n \n if (!credentials) {\n logger.error('Docker information not found. Please login first with \"phala docker login\"');\n process.exit(1);\n }\n\n let imageName = options.image;\n\n // If image name is not provided, list local images and prompt user to select\n if (!imageName) {\n const localImages = await DockerService.listLocalImages();\n \n if (localImages.length === 0) {\n logger.error('No local Docker images found. Please build an image first with \"phala docker build\"');\n process.exit(1);\n }\n\n // If no image specified, prompt to select from available images\n if (!imageName) {\n // Get unique image names\n const uniqueImageNames = Array.from(new Set(localImages.map(img => img.imageName)));\n \n const { selectedImage } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedImage',\n message: 'Select an image to push:',\n choices: uniqueImageNames\n }\n ]);\n \n imageName = selectedImage;\n }\n }\n \n // Push the image\n const dockerService = new DockerService('', credentials.username, credentials.registry);\n const success = await dockerService.pushImage(imageName);\n \n if (!success) {\n logger.error('Failed to push Docker image');\n process.exit(1);\n }\n \n logger.success(`Docker image ${imageName} pushed successfully`);\n } catch (error) {\n logger.error(`Failed to push Docker image: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { getDockerCredentials } from '@/src/utils/credentials';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { validateFileExists } from '@/src/utils/prompts';\n\nexport const generateCommand = new Command()\n .name('generate')\n .description('Generate a Docker Compose file')\n .option('-i, --image <imageName>', 'Docker image name to use in the compose file (e.g. phala/phala-cloud)')\n .option('-e, --env-file <envFile>', 'Path to environment variables file')\n .option('-o, --output <output>', 'Output path for generated docker-compose.yml')\n .option('--template <template>', 'Template to use for the generated docker-compose.yml', )\n .action(async (options) => {\n try {\n // Get Docker credentials to create the Docker service\n const credentials = await getDockerCredentials();\n if (!credentials || !credentials.username) {\n logger.error('Docker Hub username not found. Please login first with `phala docker login`');\n process.exit(1);\n }\n\n let imageName = options.image;\n\n if (!imageName) {\n // If image name is not provided, list local images and prompt user to select\n const localImages = await DockerService.listLocalImages();\n\n if (localImages.length === 0) {\n logger.error(\n 'No local Docker images found. Please build an image first with \"phala docker build\"',\n );\n process.exit(1);\n }\n\n // If no image specified, prompt to select from available images\n if (!imageName) {\n // Get unique image names\n const uniqueImageNames = Array.from(\n new Set(localImages.map((img) => img.imageName)),\n );\n\n const { selectedImage } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selectedImage\",\n message: \"Select an image to use in the compose file:\",\n choices: uniqueImageNames,\n },\n ]);\n\n imageName = selectedImage;\n }\n }\n \n // Get environment file path from options or prompt\n let envFilePath = options.envFile;\n if (!envFilePath) {\n // Check if .env exists in current directory\n const defaultEnvPath = path.join(process.cwd(), '.env');\n const hasDefaultEnv = fs.existsSync(defaultEnvPath);\n\n if (hasDefaultEnv) {\n const { useDefault } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'useDefault',\n message: 'Use .env file in current directory?',\n default: true\n }\n ]);\n\n if (useDefault) {\n envFilePath = defaultEnvPath;\n }\n }\n\n // If still no env file path, prompt for it\n if (!envFilePath) {\n const { envPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'envPath',\n message: 'Enter path to environment variables file:',\n validate: (input) => {\n try {\n validateFileExists(input);\n return true;\n } catch (error) {\n return `File not found: ${input}`;\n }\n }\n }\n ]);\n envFilePath = envPath;\n }\n } else {\n // Validate the provided env file path\n try {\n validateFileExists(envFilePath);\n } catch (error) {\n logger.error(`File not found: ${envFilePath}`);\n process.exit(1);\n }\n }\n\n // Get output path from options or set default\n let outputPath = options.output;\n if (!outputPath) {\n outputPath = path.join(process.cwd(), 'docker-compose.yml');\n \n // If file already exists, confirm overwrite\n if (fs.existsSync(outputPath)) {\n const { confirmOverwrite } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmOverwrite',\n message: `File ${outputPath} already exists. Overwrite?`,\n default: false\n }\n ]);\n if (!confirmOverwrite) {\n const { customPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'customPath',\n message: 'Enter alternative output path:',\n default: path.join(process.cwd(), 'docker-generated-compose.yml')\n }\n ]);\n outputPath = customPath;\n }\n }\n }\n \n // Create a DockerService instance\n const dockerService = new DockerService('', credentials.username, credentials.registry);\n\n // Generate the Docker Compose file\n if (envFilePath) {\n logger.info(`Generating Docker Compose file for ${imageName} using env file: ${envFilePath}`);\n } else {\n logger.info(`Generating Docker Compose file for ${imageName} without env file`);\n }\n const composePath = await dockerService.buildComposeFile(imageName, envFilePath, options.template);\n \n // Copy the generated file to the output path if needed\n if (composePath !== outputPath) {\n // Ensure the output directory exists\n const outputDir = path.dirname(outputPath);\n if (!fs.existsSync(outputDir)) {\n logger.info(`Creating directory: ${outputDir}`);\n fs.mkdirSync(outputDir, { recursive: true });\n }\n \n fs.copyFileSync(composePath, outputPath);\n }\n \n logger.success(`Docker Compose file generated successfully: ${outputPath}`);\n } catch (error) {\n logger.error(`Failed to generate Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { startCommand } from './start';\nimport { stopCommand } from './stop';\n\nexport const simulatorCommands = new Command()\n .name('simulator')\n .description('TEE simulator commands')\n .addCommand(startCommand)\n .addCommand(stopCommand);\n","import { Command } from 'commander';\nimport { DockerService } from '@/src/utils/docker';\nimport { logger } from '@/src/utils/logger';\nimport { TEE_SIMULATOR } from '@/src/utils/constants';\nimport { installSimulator, isSimulatorInstalled, isSimulatorRunning, runSimulator } from '@/src/utils/simulator';\n\nexport const startCommand = new Command()\n .name('start')\n .description('Start the TEE simulator')\n .option('-i, --image <image>', 'Simulator image', TEE_SIMULATOR)\n .option('-p, --port <port>', 'Simulator port (default: 8090)', '8090')\n .option('-t, --type <type>', 'Simulator type (docker, native)', 'docker')\n .action(async (options) => {\n try {\n if (options.type === 'docker') {\n // Start the simulator\n const dockerService = new DockerService('');\n const success = await dockerService.runSimulator(options.image, options.port);\n \n if (!success) {\n logger.error('Failed to start TEE simulator');\n process.exit(1);\n }\n } else if (options.type === 'native') {\n if (!isSimulatorInstalled()) {\n await installSimulator();\n }\n const running = await isSimulatorRunning();\n if (running) {\n logger.success('TEE simulator is already running');\n return;\n } else {\n const simulatorProcess = runSimulator();\n logger.success('TEE simulator started successfully');\n }\n } else {\n logger.error('Invalid simulator type');\n process.exit(1);\n }\n } catch (error) {\n logger.error(`Failed to start TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { DockerService } from '../../utils/docker';\nimport { logger } from '../../utils/logger';\nimport { stopSimulator } from '@/src/utils/simulator';\n\nexport const stopCommand = new Command()\n .name('stop')\n .description('Stop the TEE simulator')\n .option('-t, --type <type>', 'Simulator type (docker, native)', 'docker')\n .action(async (options) => {\n try {\n if (options.type === 'docker') {\n // Stop the simulator\n const dockerService = new DockerService('');\n const success = await dockerService.stopSimulator();\n\n if (!success) {\n logger.error('Failed to stop TEE simulator');\n process.exit(1);\n }\n } else if (options.type === 'native') {\n // Stop the native simulator\n const success = await stopSimulator();\n \n if (!success) {\n logger.error('Failed to stop TEE simulator');\n process.exit(1);\n }\n } else {\n logger.error('Invalid simulator type');\n process.exit(1);\n }\n } catch (error) {\n logger.error(`Failed to stop TEE simulator: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });","import { Command } from 'commander';\nimport { listCommand } from './list';\nimport { getCommand } from './get';\nimport { startCommand } from './start';\nimport { stopCommand } from './stop';\nimport { restartCommand } from './restart';\nimport { attestationCommand } from './attestation';\nimport { createCommand } from './create';\nimport { deleteCommand } from './delete';\nimport { upgradeCommand } from './upgrade';\nimport { resizeCommand } from './resize';\n\nexport const cvmsCommand = new Command()\n .name('cvms')\n .description('Manage Phala Confidential Virtual Machines (CVMs)')\n .addCommand(attestationCommand)\n .addCommand(createCommand)\n .addCommand(deleteCommand)\n .addCommand(getCommand)\n .addCommand(listCommand)\n .addCommand(startCommand)\n .addCommand(stopCommand)\n .addCommand(resizeCommand)\n .addCommand(restartCommand)\n .addCommand(upgradeCommand);\n ","import { Command } from 'commander';\nimport { getCvms } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { CLOUD_URL } from '@/src/utils/constants';\nimport chalk from 'chalk';\n\nexport const listCommand = new Command()\n .name('list')\n .alias('ls')\n .description('List all CVMs')\n .option('-j, --json', 'Output in JSON format')\n .action(async (options) => {\n try {\n const spinner = logger.startSpinner('Fetching CVMs');\n \n const cvms = await getCvms();\n \n spinner.stop(true);\n \n if (!cvms || cvms.length === 0) {\n logger.info('No CVMs found');\n return;\n }\n \n if (options.json) {\n console.log(JSON.stringify(cvms, null, 2));\n return;\n }\n \n for (const cvm of cvms) {\n logger.keyValueTable({\n Name: cvm.name,\n \"App ID\": `app_${cvm.hosted.app_id}`,\n Status:\n cvm.status === \"running\"\n ? chalk.green(cvm.status)\n : cvm.status === \"stopped\"\n ? chalk.red(cvm.status)\n : chalk.yellow(cvm.status),\n \"Node Info URL\": cvm.hosted.app_url,\n \"App URL\": `${CLOUD_URL}/dashboard/cvms/app_${cvm.hosted.app_id}`,\n });\n logger.break();\n }\n logger.success(`Found ${cvms.length} CVMs`);\n logger.break();\n logger.info(`Go to ${CLOUD_URL}/dashboard/ to view your CVMs`);\n } catch (error) {\n logger.error(`Failed to list CVMs: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '@/src/utils/constants';\nimport { logger } from '@/src/utils/logger';\nimport {\n cvmInstanceSchema,\n getCvmByAppIdResponseSchema,\n getPubkeyFromCvmResponseSchema,\n postCvmResponseSchema,\n upgradeCvmResponseSchema,\n cvmAttestationResponseSchema,\n getCvmNetworkResponseSchema,\n} from './types';\nimport type {\n CvmInstance,\n GetCvmByAppIdResponse,\n GetPubkeyFromCvmResponse,\n PostCvmResponse,\n UpgradeCvmResponse,\n CvmAttestationResponse,\n GetCvmNetworkResponse,\n} from './types';\nimport inquirer from 'inquirer';\nimport { z } from 'zod';\n\n/**\n * Get all CVMs for the current user\n * @returns List of CVMs\n */\nexport async function getCvms(): Promise<CvmInstance[]> {\n try {\n const response = await apiClient.get<CvmInstance[]>(API_ENDPOINTS.CVMS(0));\n return z.array(cvmInstanceSchema).parse(response);\n } catch (error) {\n throw new Error(`Failed to get CVMs: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * VM configuration type\n */\nexport interface VMConfig {\n // Add specific properties as needed\n [key: string]: unknown;\n}\n\n/**\n * Update payload type\n */\nexport interface UpdateCvmPayload {\n app_id: string;\n [key: string]: unknown;\n}\n\n/**\n * Check CVM exists for the current user and appId\n * @param appId App ID\n * @returns CVM appId string or null if it doesn't exist\n */\nexport async function checkCvmExists(appId: string): Promise<string> {\n const cvms = await getCvms();\n const cvm = cvms.find(cvm => (cvm.hosted?.app_id === appId || `app_${cvm.hosted?.app_id}` === appId));\n if (!cvm) {\n logger.error(`CVM with App ID app_${appId} not detected`);\n process.exit(1);\n } else {\n logger.success(`CVM with App ID app_${appId} detected`);\n return cvm.hosted?.app_id || '';\n }\n}\n\n/**\n * Get a CVM by App ID\n * @param appId App ID\n * @returns CVM details\n */\nexport async function getCvmByAppId(appId: string): Promise<GetCvmByAppIdResponse> {\n try {\n const response = await apiClient.get<GetCvmByAppIdResponse>(API_ENDPOINTS.CVM_BY_APP_ID(appId));\n return getCvmByAppIdResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get CVM by App ID: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get public key from CVM\n * @param vmConfig VM configuration\n * @returns Public key\n */\nexport async function getPubkeyFromCvm(vmConfig: VMConfig): Promise<GetPubkeyFromCvmResponse> {\n try {\n const response = await apiClient.post<GetPubkeyFromCvmResponse>(API_ENDPOINTS.CVM_PUBKEY, vmConfig);\n return getPubkeyFromCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get pubkey from CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get network information for a CVM\n * @param appId App ID\n * @returns Network information\n */\nexport async function getCvmNetwork(appId: string): Promise<GetCvmNetworkResponse> {\n try {\n const response = await apiClient.get<GetCvmNetworkResponse>(API_ENDPOINTS.CVM_NETWORK(appId));\n return getCvmNetworkResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to get network information for CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Create a new CVM\n * @param vmConfig VM configuration\n * @returns Created CVM details\n */\nexport async function createCvm(vmConfig: VMConfig): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_FROM_CONFIGURATION, vmConfig);\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n if (error instanceof z.ZodError) {\n logger.error('Schema validation error:', JSON.stringify(error.errors, null, 2));\n logger.error('API response:', JSON.stringify(error.format(), null, 2));\n throw new Error(`Response validation failed: ${JSON.stringify(error.errors)}`);\n }\n throw new Error(`Failed to create CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Start a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function startCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_START(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to start CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Stop a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function stopCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_STOP(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to stop CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Restart a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function restartCvm(appId: string): Promise<PostCvmResponse> {\n try {\n const response = await apiClient.post<PostCvmResponse>(API_ENDPOINTS.CVM_RESTART(appId));\n return postCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to restart CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Upgrade a CVM\n * @param appId App ID\n * @param vmConfig VM configuration\n * @returns Upgrade response\n */\nexport async function upgradeCvm(appId: string, vmConfig: VMConfig): Promise<UpgradeCvmResponse> {\n try {\n const response = await apiClient.put<UpgradeCvmResponse>(API_ENDPOINTS.CVM_UPGRADE(appId), vmConfig);\n return upgradeCvmResponseSchema.parse(response);\n } catch (error) {\n throw new Error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Delete a CVM\n * @param appId App ID\n * @returns Success status\n */\nexport async function deleteCvm(appId: string): Promise<boolean> {\n try {\n await apiClient.delete(API_ENDPOINTS.CVM_BY_APP_ID(appId));\n return true;\n } catch (error) {\n throw new Error(`Failed to delete CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Update a CVM\n * @param updatePayload Update payload\n * @returns Updated CVM details\n */\nexport async function updateCvm(updatePayload: UpdateCvmPayload): Promise<unknown> {\n try {\n const response = await apiClient.put(API_ENDPOINTS.CVM_BY_APP_ID(updatePayload.app_id), updatePayload);\n return response;\n } catch (error) {\n throw new Error(`Failed to update CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Presents a list of CVMs to the user and allows them to select one\n * @returns The selected CVM app ID or undefined if no CVMs exist\n */\nexport async function selectCvm(): Promise<string | undefined> {\n const listSpinner = logger.startSpinner('Fetching available CVMs');\n const cvms = await getCvms();\n listSpinner.stop(true);\n \n if (!cvms || cvms.length === 0) {\n logger.info('No CVMs found for your account');\n return undefined;\n }\n \n // Prepare choices for the inquirer prompt\n const choices = cvms.map(cvm => {\n // Handle different API response formats\n const id = cvm.hosted?.app_id || cvm.hosted?.id;\n const name = cvm.name || cvm.hosted?.name;\n const status = cvm.status || cvm.hosted?.status;\n \n return {\n name: `${name || 'Unnamed'} (${id}) - Status: ${status || 'Unknown'}`,\n value: id\n };\n });\n \n const { selectedCvm } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedCvm',\n message: 'Select a CVM:',\n choices\n }\n ]);\n \n return selectedCvm;\n}\n\n/**\n * Get attestation information for a CVM\n * @param appId App ID\n * @returns Attestation information\n */\nexport async function getCvmAttestation(appId: string): Promise<CvmAttestationResponse> {\n try {\n const response = await apiClient.get<CvmAttestationResponse>(API_ENDPOINTS.CVM_ATTESTATION(appId));\n \n // Attempt to validate and return the response\n try {\n return cvmAttestationResponseSchema.parse(response);\n } catch (validationError) {\n logger.debug(`Validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`);\n \n // If validation fails, create a normalized response object\n const normalizedResponse: CvmAttestationResponse = {\n is_online: Boolean(response?.is_online),\n is_public: Boolean(response?.is_public),\n error: typeof response?.error === 'string' ? response.error : null,\n app_certificates: Array.isArray(response?.app_certificates) ? response.app_certificates : null,\n tcb_info: response?.tcb_info || null,\n compose_file: typeof response?.compose_file === 'string' ? response.compose_file : null\n };\n \n return normalizedResponse;\n }\n } catch (error) {\n throw new Error(`Failed to get attestation information: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Resize payload type\n */\nexport interface ResizeCvmPayload {\n vcpu?: number;\n memory?: number;\n disk_size?: number;\n allow_restart?: number;\n}\n\n/**\n * Resize a CVM's resources\n * @param appId App ID\n * @param vcpu Number of virtual CPUs (optional)\n * @param memory Memory size in MB (optional)\n * @param diskSize Disk size in GB (optional)\n * @param allowRestart Whether to allow restart (1) or not (0) for the resize operation (optional)\n * @returns Success status\n */\nexport async function resizeCvm(\n appId: string, \n vcpu?: number, \n memory?: number, \n diskSize?: number, \n allowRestart?: number\n): Promise<boolean> {\n try {\n // Only include defined parameters in the payload\n const resizePayload: ResizeCvmPayload = {};\n \n if (vcpu !== undefined) resizePayload.vcpu = vcpu;\n if (memory !== undefined) resizePayload.memory = memory;\n if (diskSize !== undefined) resizePayload.disk_size = diskSize;\n if (allowRestart !== undefined) resizePayload.allow_restart = allowRestart;\n \n // Check if any parameters were provided\n if (Object.keys(resizePayload).length === 0) {\n throw new Error('At least one resource parameter must be provided');\n }\n \n await apiClient.patch(API_ENDPOINTS.CVM_RESIZE(appId), resizePayload);\n return true;\n } catch (error) {\n throw new Error(`Failed to resize CVM: ${error instanceof Error ? error.message : String(error)}`);\n }\n} ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmByAppId, getCvms, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { CLOUD_URL } from '@/src/utils/constants';\nimport chalk from 'chalk';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\n\nexport const getCommand = new Command()\n .name('get')\n .description('Get details of a CVM')\n .argument('[app-id]', 'App ID of the CVM (optional)')\n .option('-j, --json', 'Output in JSON format')\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n const spinner = logger.startSpinner(`Fetching CVM with App ID app_${resolvedAppId}`);\n \n const cvm = await getCvmByAppId(resolvedAppId);\n \n spinner.stop(true);\n logger.break();\n \n if (!cvm) {\n logger.error(`CVM with App ID app_${resolvedAppId} not found`);\n process.exit(1);\n }\n \n if (options.json) {\n console.log(JSON.stringify(cvm, null, 2));\n return;\n }\n \n // Display additional details if available\n logger.keyValueTable({\n 'Name': cvm.name,\n 'App ID': `app_${cvm.app_id}`,\n 'Status': (cvm.status === 'running') ? chalk.green(cvm.status) : (cvm.status === 'stopped') ? chalk.red(cvm.status) : chalk.yellow(cvm.status),\n 'vCPU': cvm.vcpu,\n 'Memory': `${cvm.memory} MB`,\n 'Disk Size': `${cvm.disk_size} GB`,\n 'Dstack Image': cvm.base_image,\n 'App URL': `${CLOUD_URL}/dashboard/cvms/app_${cvm.app_id}`\n });\n } catch (error) {\n logger.error(`Failed to get CVM details: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { selectCvm, checkCvmExists } from \"@/src/api/cvms\";\nimport { logger } from \"./logger\";\n\n/**\n * Resolves a CVM App ID either by prompting the user to select one if none is provided,\n * or by validating the provided App ID exists.\n *\n * @param appId Optional App ID to resolve\n * @returns The resolved App ID or undefined if none was selected/found\n */\nexport async function resolveCvmAppId(\n\tappId?: string,\n): Promise<string | undefined> {\n\tif (!appId) {\n\t\t// If no app ID is provided, prompt user to select one\n\t\tconst selectedCvm = await selectCvm();\n\t\tif (!selectedCvm) {\n\t\t\treturn undefined; // No CVMs found or user canceled\n\t\t}\n\t\treturn selectedCvm;\n\t}\n\t// Verify the provided App ID exists\n\treturn await checkCvmExists(appId);\n}","import { Command } from 'commander';\nimport { startCvm, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const startCommand = new Command()\n .name('start')\n .description('Start a stopped CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n const spinner = logger.startSpinner(`Starting CVM with App ID app_${resolvedAppId}`);\n \n const response = await startCvm(resolvedAppId);\n \n spinner.stop(true);\n logger.break();\n \n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n \n logger.break();\n logger.success(\n `Your CVM is being started. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to start CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { stopCvm, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const stopCommand = new Command()\n .name('stop')\n .description('Stop a running CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const spinner = logger.startSpinner(\n `Stopping CVM with App ID app_${resolvedAppId}`,\n );\n\n const response = await stopCvm(resolvedAppId);\n\n spinner.stop(true);\n logger.break();\n\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n\n logger.break();\n logger.success(\n `Your CVM is being stopped. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n \n } catch (error) {\n logger.error(`Failed to stop CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, restartCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const restartCommand = new Command()\n .name('restart')\n .description('Restart a CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .action(async (appId) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const spinner = logger.startSpinner(\n `Restarting CVM with App ID app_${resolvedAppId}`,\n );\n\n const response = await restartCvm(resolvedAppId);\n\n spinner.stop(true);\n logger.break();\n\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n 'App URL': response.app_url\n ? response.app_url\n : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: \"rounded\",\n });\n\n logger.break();\n logger.success(\n `Your CVM is being restarted. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to restart CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmAttestation, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport chalk from 'chalk';\nimport type { CvmAttestationResponse } from '@/src/api/types';\n\nexport const attestationCommand = new Command()\n .name('attestation')\n .description('Get attestation information for a CVM')\n .argument('[app-id]', 'CVM app ID (will prompt for selection if not provided)')\n .option('-j, --json', 'Output in JSON format')\n .action(async (appId?: string, options?: { json?: boolean }) => {\n try {\n let resolvedAppId: string;\n \n if (!appId) {\n logger.info('No CVM specified, fetching available CVMs...');\n const selectedCvm = await selectCvm();\n if (!selectedCvm) {\n return;\n }\n resolvedAppId = selectedCvm;\n } else {\n resolvedAppId = await checkCvmExists(appId);\n }\n\n const spinner = logger.startSpinner(`Fetching attestation information for CVM app_${resolvedAppId}...`);\n\n try {\n const attestationData: CvmAttestationResponse = await getCvmAttestation(resolvedAppId);\n spinner.stop(true);\n\n if (!attestationData || Object.keys(attestationData).length === 0) {\n logger.info('No attestation information found');\n return;\n }\n\n // If JSON output is requested, just print the raw response\n if (options?.json) {\n logger.info(JSON.stringify(attestationData, null, 2));\n return;\n }\n\n // Display the attestation summary\n logger.success('Attestation Summary:');\n const summaryData = {\n 'Status': attestationData.is_online ? chalk.green('Online') : chalk.red('Offline'),\n 'Public Access': attestationData.is_public ? chalk.green('Enabled') : chalk.yellow('Disabled'),\n 'Error': attestationData.error || 'None',\n 'Certificates': `${attestationData.app_certificates?.length || 0} found`\n };\n \n logger.keyValueTable(summaryData, {\n borderStyle: 'rounded'\n });\n\n // Display certificate information\n if (attestationData.app_certificates && attestationData.app_certificates.length > 0) {\n \n attestationData.app_certificates.forEach((cert, index) => {\n logger.break();\n logger.success(`Certificate #${index + 1} (${cert.position_in_chain === 0 ? 'End Entity' : 'CA'}):`);\n \n const certData = {\n 'Subject': `${cert.subject.common_name || 'Unknown'}${cert.subject.organization ? ` (${cert.subject.organization})` : ''}`,\n 'Issuer': `${cert.issuer.common_name || 'Unknown'}${cert.issuer.organization ? ` (${cert.issuer.organization})` : ''}`,\n 'Serial Number': cert.serial_number,\n 'Validity': `${new Date(cert.not_before).toLocaleString()} to ${new Date(cert.not_after).toLocaleString()}`,\n 'Fingerprint': cert.fingerprint,\n 'Signature Algorithm': cert.signature_algorithm,\n 'Is CA': cert.is_ca ? 'Yes' : 'No',\n 'Position in Chain': cert.position_in_chain\n };\n \n logger.keyValueTable(certData, {\n borderStyle: 'rounded'\n });\n \n // Skip displaying the quote as it's very large and mostly binary data\n });\n }\n\n // Display TCB info if available\n if (attestationData.tcb_info) {\n logger.break();\n logger.success('Trusted Computing Base (TCB) Information:');\n \n // Create a formatted version of the TCB info without the event log\n const tcbBasicInfo = {\n 'Mrtd': attestationData.tcb_info.mrtd,\n 'Rootfs Hash': attestationData.tcb_info.rootfs_hash,\n 'Rtmr0': attestationData.tcb_info.rtmr0,\n 'Rtmr1': attestationData.tcb_info.rtmr1,\n 'Rtmr2': attestationData.tcb_info.rtmr2,\n 'Rtmr3': attestationData.tcb_info.rtmr3,\n 'Event Log Entries': `${attestationData.tcb_info.event_log.length} entries`\n };\n \n // Display basic TCB info\n logger.keyValueTable(tcbBasicInfo, {\n borderStyle: 'rounded'\n });\n \n // Display event log entries separately if they exist\n if (attestationData.tcb_info.event_log && attestationData.tcb_info.event_log.length > 0) {\n logger.break();\n logger.success('Event Log (Showing entries to reproduce RTMR3):');\n \n // Show the first 5 entries\n const maxEntriesToShow = 5;\n const entries = attestationData.tcb_info.event_log\n .filter(entry => entry.event !== null && entry.event !== \"\")\n .map((entry) => ({\n 'Event': entry.event,\n 'IMR': entry.imr.toString(),\n 'Event Type': entry.event_type.toString(),\n 'Payload': entry.event_payload,\n }));\n \n // Display entries in a table format\n logger.table(entries, [\n { key: \"Event\", header: \"Event\", minWidth: 8 },\n { key: \"IMR\", header: \"IMR\", minWidth: 3 },\n { key: \"Event Type\", header: \"Type\", minWidth: 8 },\n { key: \"Payload\", header: \"Payload\", minWidth: 25 },\n ]);\n \n if (attestationData.tcb_info.event_log.length > maxEntriesToShow) {\n logger.info('To see all full attestation data, use --json');\n }\n logger.break();\n logger.success('To reproduce RTMR3, use the tool at https://rtmr3-calculator.vercel.app/');\n }\n }\n } catch (error) {\n spinner.stop(false);\n throw error;\n }\n } catch (error) {\n logger.error(`Failed to get attestation information: ${error instanceof Error ? error.message : String(error)}`);\n }\n });\n","import { Command } from 'commander';\nimport { createCvm, getPubkeyFromCvm } from '@/src/api/cvms';\nimport { getTeepods } from '@/src/api/teepods';\nimport { logger } from '@/src/utils/logger';\nimport type { TEEPod, Image } from '@/src/api/types';\nimport { DEFAULT_VCPU, DEFAULT_MEMORY, DEFAULT_DISK_SIZE, CLOUD_URL } from '@/src/utils/constants';\nimport { encryptEnvVars, type EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport inquirer from 'inquirer';\nimport { parseEnv } from '@/src/utils/secrets';\nimport { detectFileInCurrentDir, promptForFile } from '@/src/utils/prompts';\nimport { deleteSimulatorEndpointEnv } from '@/src/utils/simulator';\n\nexport const createCommand = new Command()\n .name('create')\n .description('Create a new CVM')\n .option('-n, --name <name>', 'Name of the CVM')\n .option('-c, --compose <compose>', 'Path to Docker Compose file')\n .option('--vcpu <vcpu>', `Number of vCPUs, default is ${DEFAULT_VCPU}`)\n .option('--memory <memory>', `Memory in MB, default is ${DEFAULT_MEMORY}`)\n .option('--disk-size <diskSize>', `Disk size in GB, default is ${DEFAULT_DISK_SIZE}`)\n .option('--teepod-id <teepodId>', 'TEEPod ID to use. If not provided, it will be selected from the list of available TEEPods.')\n .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.')\n .option('-e, --env-file <envFile>', 'Path to environment file')\n .option('--skip-env', 'Skip environment variable prompt', false)\n .option('--debug', 'Enable debug mode', false)\n .action(async (options) => {\n try {\n // Prompt for required options if not provided\n if (!options.name) {\n const { name } = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Enter a name for the CVM:',\n validate: (input) => {\n if (!input.trim()) {\n return 'CVM name is required';\n }\n if (input.trim().length > 20) {\n return 'CVM name must be less than 20 characters';\n } else if (input.trim().length < 3) {\n return 'CVM name must be at least 3 characters';\n } else if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return 'CVM name must contain only letters, numbers, underscores, and hyphens';\n }\n return true;\n }\n }\n ]);\n options.name = name;\n }\n\n // If compose path not provided, prompt with examples\n if (!options.compose) {\n const possibleFiles = ['docker-compose.yml', 'docker-compose.yaml'];\n const composeFileName = detectFileInCurrentDir(possibleFiles, 'Detected docker compose file: {path}');\n\n options.compose = await promptForFile(\n 'Enter the path to your Docker Compose file:',\n composeFileName,\n 'file'\n );\n }\n\n const composePath = path.resolve(options.compose);\n if (!fs.existsSync(composePath)) {\n logger.error(`Docker Compose file not found: ${composePath}`);\n process.exit(1);\n }\n const composeString = fs.readFileSync(composePath, 'utf8');\n\n // Delete DSTACK_SIMULATOR_ENDPOINT environment variable\n await deleteSimulatorEndpointEnv();\n\n // Process environment variables\n let envs: EnvVar[] = [];\n\n // Process environment variables from file\n if (options.envFile) {\n try {\n envs = parseEnv([], options.envFile);\n } catch (error) {\n logger.error(`Failed to read environment file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n } else if (!options.skipEnv) {\n // Prompt to input env file or skip\n const { shouldSkip } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldSkip',\n message: 'Do you want to skip environment variable prompt?',\n default: true\n }\n ]);\n \n if (shouldSkip) {\n logger.info('Skipping environment variable prompt');\n } else {\n const envVars = await promptForFile(\n 'Enter the path to your environment file:',\n '.env',\n 'file',\n );\n envs = parseEnv([], envVars);\n }\n }\n\n const vcpu = Number(options.vcpu) || DEFAULT_VCPU;\n const memory = Number(options.memory) || DEFAULT_MEMORY;\n const diskSize = Number(options.diskSize) || DEFAULT_DISK_SIZE;\n\n if (isNaN(vcpu) || vcpu <= 0) {\n logger.error(`Invalid number of vCPUs: ${vcpu}`);\n process.exit(1);\n }\n\n if (isNaN(memory) || memory <= 0) {\n logger.error(`Invalid memory: ${memory}`);\n process.exit(1);\n }\n\n if (isNaN(diskSize) || diskSize <= 0) {\n logger.error(`Invalid disk size: ${diskSize}`);\n process.exit(1);\n }\n\n const teepodsSpinner = logger.startSpinner('Fetching available TEEPods');\n const teepods = await getTeepods();\n teepodsSpinner.stop(true);\n if (teepods.length === 0) {\n logger.error('No TEEPods available. Please try again later.');\n process.exit(1);\n }\n\n let selectedTeepod: TEEPod;\n // Fetch available TEEPods\n if (!options.teepodId) {\n selectedTeepod = teepods[0];\n } else {\n selectedTeepod = teepods.find(pod => pod.teepod_id === options.teepodId);\n if (!selectedTeepod) {\n logger.error('Failed to find selected TEEPod');\n process.exit(1);\n }\n }\n\n let selectedImage: Image;\n if (!options.image) {\n selectedImage = selectedTeepod.images![0];\n } else {\n const selectedImage = selectedTeepod.images?.find(image => image.name === options.image);\n if (!selectedImage) {\n logger.error(`Failed to find selected image: ${options.image}`);\n process.exit(1);\n }\n }\n\n // Prepare VM configuration\n const vmConfig = {\n teepod_id: selectedTeepod.teepod_id,\n name: options.name,\n image: selectedImage.name,\n vcpu: vcpu,\n memory: memory,\n disk_size: diskSize,\n compose_manifest: {\n docker_compose_file: composeString,\n docker_config: {\n url: '',\n username: '',\n password: '',\n },\n features: ['kms', 'tproxy-net'],\n kms_enabled: true,\n manifest_version: 2,\n name: options.name,\n public_logs: true,\n public_sysinfo: true,\n tproxy_enabled: true,\n },\n listed: false,\n };\n\n // Get public key from CVM\n const spinner = logger.startSpinner('Getting public key from CVM');\n const pubkey = await getPubkeyFromCvm(vmConfig);\n spinner.stop(true);\n\n if (!pubkey) {\n logger.error('Failed to get public key from CVM');\n process.exit(1);\n }\n\n // Encrypt environment variables\n const encryptSpinner = logger.startSpinner('Encrypting environment variables');\n const encrypted_env = await encryptEnvVars(envs, pubkey.app_env_encrypt_pubkey);\n encryptSpinner.stop(true);\n\n if (options.debug) {\n logger.debug('Public key:', pubkey.app_env_encrypt_pubkey);\n logger.debug('Encrypted environment variables:', encrypted_env);\n logger.debug('Environment variables:', JSON.stringify(envs));\n }\n\n // Create the CVM\n const createSpinner = logger.startSpinner('Creating CVM');\n const response = await createCvm({\n ...vmConfig,\n encrypted_env,\n app_env_encrypt_pubkey: pubkey.app_env_encrypt_pubkey,\n app_id_salt: pubkey.app_id_salt,\n });\n createSpinner.stop(true);\n\n if (!response) {\n logger.error('Failed to create CVM');\n process.exit(1);\n }\n\n logger.success('CVM created successfully');\n logger.break();\n const tableData = {\n 'CVM ID': response.id,\n 'Name': response.name,\n 'Status': response.status,\n 'App ID': `app_${response.app_id}`,\n 'App URL': response.app_url ? response.app_url : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n };\n logger.keyValueTable(tableData, {\n borderStyle: 'rounded'\n });\n\n logger.info('');\n logger.success(`Your CVM is being created. You can check its status with:\\nphala cvms get app_${response.app_id}`);\n } catch (error) {\n logger.error(`Failed to create CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { apiClient } from './client';\nimport { API_ENDPOINTS } from '../utils/constants';\nimport { TEEPod, Image, teepodSchema, imageSchema, TeepodResponse, teepodResponseSchema } from './types';\nimport { z } from 'zod';\n\n/**\n * Get all TEEPods with their images\n * @returns List of TEEPods with embedded images\n */\nexport async function getTeepods(): Promise<TEEPod[]> {\n try {\n const response = await apiClient.get<TeepodResponse>(API_ENDPOINTS.TEEPODS);\n const parsedResponse = teepodResponseSchema.parse(response);\n return parsedResponse.nodes;\n } catch (error) {\n throw new Error(`Failed to get TEEPods: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get images for a TEEPod\n * This function is maintained for backwards compatibility.\n * Images are now included directly in the TEEPod response.\n * \n * @param teepodId TEEPod ID\n * @returns List of images for the TEEPod\n */\nexport async function getTeepodImages(teepodId: string): Promise<Image[]> {\n try {\n // First try to get TEEPod with embedded images\n const teepods = await getTeepods();\n const teepod = teepods.find(pod => pod.teepod_id === Number(teepodId));\n \n // If we found the TEEPod and it has images, return them\n if (teepod && teepod.images && teepod.images.length > 0) {\n return teepod.images;\n }\n \n // Fallback to the original implementation\n const response = await apiClient.get<Image[]>(API_ENDPOINTS.TEEPOD_IMAGES(teepodId));\n return z.array(imageSchema).parse(response);\n } catch (error) {\n throw new Error(`Failed to get TEEPod images: ${error instanceof Error ? error.message : String(error)}`);\n }\n} ","import fs from 'node:fs';\nimport type { EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\n\nexport const parseEnv = (envs: string[], envFile: string): EnvVar[] => {\n // Process environment variables\n const envVars: Record<string, string> = {};\n if (envs) {\n for (const env of envs) {\n if (env.includes(\"=\")) {\n const [key, value] = env.split(\"=\");\n if (key && value) {\n envVars[key] = value;\n }\n }\n }\n }\n\n if (envFile) {\n const envFileContent = fs.readFileSync(envFile, \"utf8\");\n for (const line of envFileContent.split(\"\\n\")) {\n // Skip empty lines or comment lines\n if (!line.trim() || line.trim().startsWith('#')) continue;\n \n if (line.includes(\"=\")) {\n // Split only on the first equals sign\n const [key, ...valueParts] = line.split(\"=\");\n let value = valueParts.join(\"=\");\n \n // Remove inline comments (anything after # with whitespace before it)\n const commentIndex = value.search(/\\s+#/);\n if (commentIndex !== -1) {\n value = value.substring(0, commentIndex).trim();\n }\n \n if (key && value) {\n envVars[key.trim()] = value.trim();\n }\n }\n }\n }\n\n // Add environment variables to the payload\n return Object.entries(envVars).map(([key, value]) => ({\n key,\n value,\n }));\n};","import { Command } from 'commander';\nimport { checkCvmExists, deleteCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\n\nexport const deleteCommand = new Command()\n .name('delete')\n .description('Delete a CVM')\n .argument('[app-id]', 'App ID of the CVM to delete (if not provided, a selection prompt will appear)')\n .option('-f, --force', 'Skip confirmation prompt', false)\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n \n // Confirm deletion unless force option is used\n if (!options.force) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Are you sure you want to delete CVM with App ID app_${resolvedAppId}? This action cannot be undone.`,\n default: false,\n },\n ]);\n \n if (!confirm) {\n logger.info('Deletion cancelled');\n return;\n }\n }\n \n // Delete the CVM\n const spinner = logger.startSpinner(`Deleting CVM app_${resolvedAppId}`);\n const success = await deleteCvm(resolvedAppId);\n spinner.stop(true);\n \n if (!success) {\n logger.error(`Failed to delete CVM app_${resolvedAppId}`);\n process.exit(1);\n }\n\n\t\tlogger.success(`CVM app_${resolvedAppId} deleted successfully`);\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t`Failed to delete CVM: ${error instanceof Error ? error.message : String(error)}`\n\t\t);\n\t\tprocess.exit(1);\n\t}\n }); ","import { Command } from 'commander';\nimport { upgradeCvm, getCvmByAppId, selectCvm, checkCvmExists } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport fs from 'node:fs';\nimport { detectFileInCurrentDir, promptForFile } from '@/src/utils/prompts';\nimport { parseEnv } from '@/src/utils/secrets';\nimport { encryptEnvVars, type EnvVar } from '@phala/dstack-sdk/encrypt-env-vars';\nimport { deleteSimulatorEndpointEnv } from '@/src/utils/simulator';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const upgradeCommand = new Command()\n .name('upgrade')\n .description('Upgrade a CVM to a new version')\n .argument('[app-id]', 'CVM app ID to upgrade (will prompt for selection if not provided)')\n .option('-c, --compose <compose>', 'Path to new Docker Compose file')\n .option('-e, --env-file <envFile>', 'Path to environment file')\n .option('--debug', 'Enable debug mode', false)\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n // Get current CVM configuration\n const spinner = logger.startSpinner(`Fetching current configuration for CVM app_${resolvedAppId}`);\n const currentCvm = await getCvmByAppId(resolvedAppId);\n spinner.stop(true);\n \n if (!currentCvm) {\n logger.error(`CVM with App ID app_${resolvedAppId} not found`);\n process.exit(1);\n }\n \n // If compose path not provided, prompt with examples\n if (!options.compose) {\n const possibleFiles = ['docker-compose.yml', 'docker-compose.yaml'];\n const composeFileName = detectFileInCurrentDir(possibleFiles, 'Detected docker compose file: {path}');\n \n options.compose = await promptForFile(\n 'Enter the path to your Docker Compose file:',\n composeFileName,\n 'file'\n );\n }\n \n // Update Docker Compose file if provided\n let composeString = '';\n if (options.compose) {\n try {\n composeString = fs.readFileSync(options.compose, 'utf8');\n } catch (error) {\n logger.error(`Failed to read Docker Compose file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }\n \n // Delete DSTACK_SIMULATOR_ENDPOINT environment variable\n await deleteSimulatorEndpointEnv();\n\n // Process environment variables if provided\n let encrypted_env = \"\";\n if (options.envFile) {\n let envs: EnvVar[] = [];\n \n // Process environment variables from file\n if (options.envFile) {\n try {\n envs = parseEnv([], options.envFile);\n encrypted_env = await encryptEnvVars(envs, currentCvm.encrypted_env_pubkey);\n } catch (error) {\n logger.error(`Failed to read environment file: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }\n \n }\n\n const vm_config = {\n compose_manifest: {\n docker_compose_file: composeString,\n manifest_version: 1,\n runner: \"docker-compose\",\n version: \"1.0.0\",\n features: [\"kms\", \"tproxy-net\"],\n name: `app_${resolvedAppId}`,\n },\n encrypted_env,\n allow_restart: true,\n };\n \n // Upgrade the CVM\n const upgradeSpinner = logger.startSpinner(`Upgrading CVM app_${resolvedAppId}`);\n const response = await upgradeCvm(resolvedAppId, vm_config);\n \n if (!response) {\n upgradeSpinner.stop(false);\n logger.error('Failed to upgrade CVM');\n process.exit(1);\n }\n upgradeSpinner.stop(true);\n\n if (response.detail) {\n logger.info(`Details: ${response.detail}`);\n }\n\n logger.break();\n logger.success(\n `Your CVM is being upgraded. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${resolvedAppId}`\n );\n } catch (error) {\n logger.error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { checkCvmExists, getCvmByAppId, resizeCvm, selectCvm } from '@/src/api/cvms';\nimport { logger } from '@/src/utils/logger';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { resolveCvmAppId } from '@/src/utils/cvms';\nimport { CLOUD_URL } from '@/src/utils/constants';\n\nexport const resizeCommand = new Command()\n .name('resize')\n .description('Resize resources for a CVM')\n .argument('[app-id]', 'App ID of the CVM (if not provided, a selection prompt will appear)')\n .option('-v, --vcpu <vcpu>', 'Number of virtual CPUs')\n .option('-m, --memory <memory>', 'Memory size in MB')\n .option('-d, --disk-size <diskSize>', 'Disk size in GB')\n .option('-r, --allow-restart <allowRestart>', 'Allow restart of the CVM if needed for resizing')\n .option('-y, --yes', 'Automatically confirm the resize operation')\n .action(async (appId, options) => {\n try {\n const resolvedAppId = await resolveCvmAppId(appId);\n\n const cvm = await getCvmByAppId(resolvedAppId);\n \n // Initialize parameters\n let vcpu: number | undefined = options.vcpu;\n let memory: number | undefined = options.memory;\n let diskSize: number | undefined = options.diskSize;\n let allowRestart: boolean | undefined = options.allowRestart;\n // Prompt for vCPU if selected\n if (!vcpu) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'vcpu',\n message: 'Enter number of vCPUs:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.vcpu,\n filter: (input) => parseInt(input)\n }\n ]);\n vcpu = response.vcpu;\n }\n \n // Prompt for memory\n if (!memory) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'memory',\n message: 'Enter memory in MB:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.memory,\n filter: (input) => parseInt(input)\n }\n ]);\n memory = response.memory;\n }\n \n // Prompt for disk size\n if (!diskSize) {\n const response = await inquirer.prompt([\n {\n type: 'input',\n name: 'diskSize',\n message: 'Enter disk size in GB:',\n validate: (input) => {\n const num = parseInt(input);\n if (isNaN(num) || num < 0) {\n return 'Please enter a valid non-negative number';\n }\n return true;\n },\n default: cvm.disk_size,\n filter: (input) => parseInt(input)\n }\n ]);\n diskSize = response.diskSize;\n }\n \n // Ask about restart permission\n if (!allowRestart) {\n const response = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'allowRestart',\n message: 'Allow restart of the CVM if needed for resizing?',\n default: false\n }\n ]);\n allowRestart = response.allowRestart;\n }\n \n // Prepare confirmation message\n const confirmMessage = `Are you sure you want to resize CVM app_${resolvedAppId} with the following changes:\\n`;\n logger.keyValueTable(\n { 'vCPUs': cvm.vcpu !== vcpu ? `${chalk.red(cvm.vcpu)} -> ${chalk.green(vcpu)}` : cvm.vcpu,\n 'Memory': cvm.memory !== memory ? `${chalk.red(cvm.memory)} MB -> ${chalk.green(memory)} MB` : cvm.memory,\n 'Disk Size': cvm.disk_size !== diskSize ? `${chalk.red(cvm.disk_size)} GB -> ${chalk.green(diskSize)} GB` : cvm.disk_size,\n 'Allow Restart': allowRestart ? chalk.green('Yes') : chalk.red('No') }\n );\n \n // Confirm the resize operation\n if (!options.yes) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: confirmMessage,\n default: false\n }\n ]);\n \n if (!confirm) {\n logger.info('Resize operation cancelled');\n return;\n }\n }\n \n const spinner = logger.startSpinner(`Resizing CVM with App ID app_${resolvedAppId}`);\n \n // Convert boolean to number (0 or 1) as expected by the API\n const allowRestartValue = allowRestart ? 1 : 0;\n \n await resizeCvm(resolvedAppId, vcpu, memory, diskSize, allowRestartValue);\n\n spinner.stop(true);\n logger.break();\n logger.success(\n `Your CVM is being resized. You can check the dashboard for more details:\\n${CLOUD_URL}/dashboard/cvms/app_${resolvedAppId}`\n );\n } catch (error) {\n logger.error(\n `Failed to resize CVM: ${error instanceof Error ? error.message : String(error)}`\n );\n process.exit(1);\n }\n }); ","import { Command } from 'commander';\nimport { logger } from '@/src/utils/logger';\nimport { execSync } from 'node:child_process';\nimport * as os from 'node:os';\nimport { logo } from '../utils/banner';\n\n\n/**\n * Opens a URL in the default web browser based on the current operating system\n * @param url The URL to open\n */\nfunction openBrowser(url: string): void {\n const platform = os.platform();\n \n try {\n switch (platform) {\n case 'darwin': // macOS\n execSync(`open \"${url}\"`);\n break;\n case 'win32': // Windows\n execSync(`start \"\" \"${url}\"`);\n break;\n case 'linux': // Linux\n // Try different commands in order\n try {\n execSync(`xdg-open \"${url}\"`);\n } catch (error) {\n try {\n execSync(`gnome-open \"${url}\"`);\n } catch (error) {\n execSync(`kde-open \"${url}\"`);\n }\n }\n break;\n default:\n throw new Error(`Unsupported platform: ${platform}`);\n }\n logger.success(`Opened URL in your default browser: ${url}`);\n } catch (error) {\n logger.error(`Failed to open URL: ${error instanceof Error ? error.message : String(error)}`);\n logger.info(`Please manually open this URL in your browser: ${url}`);\n }\n}\n\n/**\n * Pauses execution for the specified number of milliseconds\n * @param {number} ms - Time to sleep in milliseconds\n * @returns {Promise} Promise that resolves after the specified time\n */\nfunction sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport const joinCommand = new Command()\n .name('join')\n .alias('free')\n .description('Join Phala Cloud! Get an account and deploy a CVM for FREE')\n .action(async () => {\n try {\n const inviteUrl = 'https://cloud.phala.network/register?invite=PHALACLI';\n const spinner =logger.startSpinner('Brewing a fresh cup of TEE 🍵');\n await sleep(2000);\n spinner.stop(true);\n logger.break();\n logger.break();\n console.log(logo);\n logger.info('TEE is served! Opening Phala Cloud registration page...');\n await sleep(1000);\n logger.break()\n openBrowser(inviteUrl);\n } catch (error) {\n logger.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n }); ","import { Command } from \"commander\";\nimport { logger } from \"@/src/utils/logger\";\nimport { getApiKey } from \"@/src/utils/credentials\";\nimport { getUserInfo } from \"@/src/api/auth\";\nimport { createCvm, getPubkeyFromCvm } from \"@/src/api/cvms\";\nimport { DEFAULT_IMAGE, CLOUD_URL } from \"@/src/utils/constants\";\nimport { demoTemplates } from \"@/src/utils/demo\";\nimport {\n\tencryptEnvVars,\n\ttype EnvVar,\n} from \"@phala/dstack-sdk/encrypt-env-vars\";\nimport inquirer from \"inquirer\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { parseEnv } from \"@/src/utils/secrets\";\n\nexport const demoCommands = new Command()\n .name(\"demo\")\n .description(\"Demo commands to launch a demo on Phala Cloud\")\n .action(async () => {\n try {\n // 1. Check if the user is logged in\n const apiKey = await getApiKey();\n if (!apiKey) {\n logger.error(\"You need to be logged in to use the demo command\");\n logger.info(\"Please login with: phala auth login\");\n process.exit(1);\n }\n\n // Verify user credentials\n try {\n const spinner = logger.startSpinner(\"Verifying your credentials\");\n const userInfo = await getUserInfo();\n spinner.stop(true);\n logger.success(`Logged in as ${userInfo.username}`);\n } catch (error) {\n logger.error(\"Authentication failed. Your API key may be invalid or expired.\");\n logger.info(\"Please set a new API key with: phala auth login\");\n process.exit(1);\n }\n\n // 2. Get list of available templates\n const templates = Object.values(demoTemplates);\n\n if (templates.length === 0) {\n logger.error(\"No template files found in the templates directory\");\n process.exit(1);\n }\n\n // 3. Prompt user to select a template\n const { selectedTemplate } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selectedTemplate\",\n message: \"Select a template to deploy:\",\n choices: templates.map(t => ({\n name: t.name,\n value: t\n }))\n }\n ]);\n\n // 4. Read the selected template\n const templateContent = selectedTemplate.compose;\n logger.success(`Selected template: ${selectedTemplate.name}`);\n\n // 5. Generate a random token for services that might need it\n const token = crypto.randomBytes(16).toString(\"hex\");\n const envVars = parseEnv([`TOKEN=${token}`], \"\");\n \n \n // 6. Ask for CVM name\n const { cvmName } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"cvmName\",\n message: \"Enter a name for your CVM:\",\n default: `${selectedTemplate.name.replace(\" \", \"-\")}`,\n validate: (input) => {\n if (!input.trim()) {\n return \"CVM name is required\";\n }\n return true;\n }\n }\n ]);\n\n // 7. Deploy the CVM with the specified resources\n logger.info(\"Preparing to deploy your CVM...\");\n \n // Prepare VM configuration with specified resources\n const vmConfig = {\n teepod_id: 3,\n name: cvmName,\n image: DEFAULT_IMAGE,\n vcpu: 2,\n memory: 2048,\n disk_size: 20,\n compose_manifest: {\n docker_compose_file: templateContent,\n docker_config: {\n url: \"\",\n username: \"\",\n password: \"\",\n },\n features: [\"kms\", \"tproxy-net\"],\n kms_enabled: true,\n manifest_version: 2,\n name: cvmName,\n public_logs: true,\n public_sysinfo: true,\n tproxy_enabled: true,\n },\n listed: false,\n };\n\n // Get public key from CVM for the API call structure\n const spinner = logger.startSpinner(\"Preparing CVM configuration\");\n const pubkey = await getPubkeyFromCvm(vmConfig);\n spinner.stop(true);\n \n if (!pubkey) {\n logger.error(\"Failed to prepare CVM configuration\");\n process.exit(1);\n }\n\n const encrypted_env = await encryptEnvVars(\n\t\t\t\t\t\t\tenvVars,\n\t\t\t\t\t\t\tpubkey.app_env_encrypt_pubkey,\n\t\t\t\t\t\t);\n\n logger.debug(\"Public key:\", pubkey.app_env_encrypt_pubkey);\n logger.debug(\"Encrypted environment variables:\", encrypted_env);\n // Create the CVM\n const createSpinner = logger.startSpinner(\"Creating your demo CVM\");\n const response = await createCvm({\n ...vmConfig,\n encrypted_env,\n app_env_encrypt_pubkey: pubkey.app_env_encrypt_pubkey,\n app_id_salt: pubkey.app_id_salt,\n });\n createSpinner.stop(true);\n\n if (!response) {\n logger.error(\"Failed to create demo CVM\");\n process.exit(1);\n }\n\n logger.success(\"Demo CVM created successfully! 🎉\");\n logger.break();\n \n const tableData = {\n \"CVM ID\": response.id,\n \"Name\": response.name,\n \"Status\": response.status,\n \"App ID\": `app_${response.app_id}`,\n \"App URL\": response.app_url ? response.app_url : `${CLOUD_URL}/dashboard/cvms/app_${response.app_id}`,\n \"Template\": selectedTemplate.name,\n \"Resources\": \"2 vCPUs, 2GB RAM, 20GB Storage\",\n };\n \n if (selectedTemplate.name.includes(\"Jupyter Notebook\")) {\n tableData[\"Jupyter Token\"] = token;\n tableData[\"Access Instructions\"] = \"Access your Jupyter notebook using the token above. Go to 'Network' tab to see the public URL.\";\n }\n \n logger.keyValueTable(tableData, {\n borderStyle: \"rounded\"\n });\n\n logger.break();\n logger.success(`Your demo is being created. You can check its status with:\\nphala cvms get app_${response.app_id}`);\n\n } catch (error) {\n logger.error(`Failed to launch demo: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n","const jupyterCompose = `version: '3'\nservices:\n jupyter:\n image: quay.io/jupyter/base-notebook\n ports:\n - 8080:8888\n volumes:\n - /var/run/tappd.sock:/var/run/tappd.sock\n environment:\n - GRANT_SUDO=yes\n user: root\n command: \"start-notebook.sh --NotebookApp.token=\\${TOKEN}\"\n`;\n\nexport const httpbinCompose = `version: '3'\nservices:\n httpbin:\n image: kennethreitz/httpbin:latest\n ports:\n - \"80:80\"\n`;\n\n\nexport const demoTemplates = {\n jupyter: {\n compose: jupyterCompose,\n name: \"Jupyter Notebook\",\n },\n httpbin: {\n compose: httpbinCompose,\n name: \"HTTPBin\",\n },\n};\n"],"mappings":"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","names":["Command","chalk","logoColor","logo","smallLogo","minimalLogo","Command","Command","fs","path","os","crypto","chalk","stripAnsi","str","pattern","getVisibleLength","wrapText","text","maxWidth","lines","currentLine","currentLineVisibleLength","words","word","wordVisibleLength","logger","message","args","data","columns","columnConfig","col","formatTable","options","mergedOptions","key","commonAcronyms","customTerms","formatted","part","acronym","regex","term","replacement","value","include","exclude","keyFormatter","valueFormatter","formatKeys","keyWidth","valueWidth","borderStyle","enableTextWrapping","maxDepth","keys","tableData","formattedValue","formatNestedObject","terminalWidth","getTerminalWidth","finalKeyWidth","finalValueWidth","item","borderChars","maxValueWidth","border","getBorderChars","topBorder","headerSeparator","row","index","keyLines","valueLines","maxLines","i","keyLine","valueLine","keyContent","valueContent","bottomBorder","success","result","icon","resultText","obj","currentDepth","style","calculateColumnWidths","borderCharsPerColumn","totalBorderWidth","availableContentWidth","initialWidths","totalFixedWidth","totalWeight","column","minWidth","contentWidth","remainingWidth","extraWidth","calculatedTotalWidth","sum","width","scale","finalWidths","formatTable","data","options","obj","keyValueData","key","col","value","parts","current","part","chalk","mergedOptions","text","columns","sample","border","columnConfig","item","widths","calculateColumnWidths","formattedColumns","index","headers","formatRow","row","rowIndex","rowData","displayValue","wrapText","maxLines","formattedLines","lineIndex","lineContent","colIndex","content","topBorder","wrappedHeaders","i","maxHeaderLines","h","headerLine","header","headerSeparator","formattedRows","rowLine","cell","rowSeparator","bottomBorder","PHALA_CLOUD_DIR","path","os","API_KEY_FILE","DOCKER_CREDENTIALS_FILE","ensureDirectoryExists","fs","error","logger","getMachineKey","machineParts","hash","crypto","encrypt","text","key","iv","cipher","encrypted","decrypt","encryptedText","parts","decipher","decrypted","saveApiKey","apiKey","encryptedApiKey","getApiKey","removeApiKey","saveDockerCredentials","credentials","getDockerCredentials","data","prompts","axios","CLOUD_API_URL","CLOUD_URL","CLI_VERSION","TEE_SIMULATOR","DEFAULT_VCPU","DEFAULT_MEMORY","DEFAULT_DISK_SIZE","DEFAULT_IMAGE","API_ENDPOINTS","teepodId","userId","appId","DOCKER_COMPOSE_ELIZA_V2_TEMPLATE","DOCKER_COMPOSE_BASIC_TEMPLATE","safeStringify","obj","error","ApiClient","baseURL","logger","axios","CLI_VERSION","config","getApiKey","response","status","data","url","CLOUD_API_URL","apiClient","z","INVALID","ParseStatus","ZodIssueCode","ZodParsedType","ZodType","addIssueToContext","z","zodDecimalKind","precisionRegex","_ZodDecimal","ZodType","input","ZodParsedType","ctx","addIssueToContext","ZodIssueCode","INVALID","status","ParseStatus","check","parts","kind","value","inclusive","message","min","ch","max","ZodDecimal","__publicField","params","ComposeTemplateSchema","z","dockerConfigSchema","z","composeFileSchema","configurationSchema","hostedSchema","managedUserSchema","nodeSchema","cvmInstanceSchema","postCvmResponseSchema","getPubkeyFromCvmResponseSchema","getCvmByAppIdResponseSchema","getUserInfoResponseSchema","ZodDecimal","getCvmsByUserIdResponseSchema","upgradeCvmResponseSchema","encryptedEnvItemSchema","imageSchema","teepodSchema","capacitySchema","teepodResponseSchema","getCvmNetworkResponseSchema","cvmAttestationResponseSchema","safeStringify","obj","error","getUserInfo","logger","API_ENDPOINTS","response","apiClient","getUserInfoResponseSchema","parseError","loginCommand","Command","apiKey","checkUserInfo","prompts","value","saveApiKey","getUserInfo","removeApiKey","logger","CLOUD_URL","error","Command","logoutCommand","Command","removeApiKey","logger","error","Command","statusCommand","Command","options","apiKey","getApiKey","logger","spinner","userInfo","getUserInfo","tableData","error","authCommands","Command","loginCommand","logoutCommand","statusCommand","Command","Command","execa","fs","path","Handlebars","exec","spawn","promisify","os","inquirer","fs","path","validateFileExists","filePath","basePath","resolvedPath","path","fs","promptForFile","message","defaultValue","name","inquirer","input","detectFileInCurrentDir","possibleFiles","logMessage","file","logger","fs","path","os","execSync","spawn","net","SIMULATOR_CONFIG","isSimulatorInstalled","platform","extractedFolderPath","executablePath","error","logger","getPlatform","installSimulator","progressCallback","log","message","platformConfig","downloadUrl","execSync","runSimulator","options","executableName","runOptions","logDir","stdio","outputStream","simulatorProcess","spawn","timestamp","setSimulatorEndpointEnv","isSimulatorRunning","platform","getPlatform","platformConfig","SIMULATOR_CONFIG","socketPath","resolve","client","host","error","logger","stopSimulator","execSync","stopped","deleteSimulatorEndpointEnv","getSimulatorEndpoint","getPlatform","setSimulatorEndpointEnv","endpoint","simulatorEndpoint","envEndpoint","execSync","logger","error","deleteSimulatorEndpointEnv","execAsync","promisify","exec","LOGS_DIR","COMPOSE_FILES_DIR","MAX_CONSOLE_LINES","DockerService","image","username","registry","logsPath","path","fs","operation","timestamp","arch","os","command","args","resolve","reject","proc","spawn","logFile","logStream","consoleBuffer","processOutput","data","isError","lines","line","bufferedLine","code","err","dockerfile","tag","fullImageName","spinner","logger","validateFileExists","buildArgs","error","imageName","getDockerCredentials","password","execa","loginError","homeDir","dockerConfigPath","dockerConfig","envFile","templateType","template","DOCKER_COMPOSE_ELIZA_V2_TEMPLATE","DOCKER_COMPOSE_BASIC_TEMPLATE","validatedTemplate","ComposeTemplateSchema","composePath","envVars","commentIndex","key","value","trimmedKey","composeContent","Handlebars","env","composeFile","composeArgs","port","stdout","containerId","setSimulatorEndpointEnv","deleteSimulatorEndpointEnv","prompts","loginCommand","Command","options","username","password","registry","logger","response","value","dockerService","DockerService","saveDockerCredentials","error","Command","path","inquirer","fs","buildCommand","Command","options","credentials","getDockerCredentials","logger","response","inquirer","input","defaultPath","path","fs","promptForFile","dockerfilePath","DockerService","error","Command","inquirer","pushCommand","Command","options","credentials","getDockerCredentials","logger","imageName","localImages","DockerService","uniqueImageNames","img","selectedImage","error","Command","inquirer","fs","path","generateCommand","Command","options","credentials","getDockerCredentials","logger","imageName","localImages","DockerService","uniqueImageNames","img","selectedImage","inquirer","envFilePath","validateFileExists","defaultEnvPath","path","fs","useDefault","envPath","input","outputPath","confirmOverwrite","customPath","dockerService","composePath","outputDir","error","dockerCommands","Command","loginCommand","buildCommand","pushCommand","generateCommand","Command","Command","startCommand","Command","TEE_SIMULATOR","options","DockerService","logger","isSimulatorInstalled","installSimulator","isSimulatorRunning","simulatorProcess","runSimulator","error","Command","stopCommand","Command","options","DockerService","logger","stopSimulator","error","simulatorCommands","Command","startCommand","stopCommand","Command","Command","inquirer","z","getCvms","response","apiClient","API_ENDPOINTS","cvmInstanceSchema","error","checkCvmExists","appId","cvm","logger","getCvmByAppId","getCvmByAppIdResponseSchema","getPubkeyFromCvm","vmConfig","getPubkeyFromCvmResponseSchema","createCvm","vmConfig","response","apiClient","API_ENDPOINTS","postCvmResponseSchema","error","z","logger","startCvm","appId","stopCvm","restartCvm","upgradeCvm","upgradeCvmResponseSchema","deleteCvm","selectCvm","listSpinner","logger","cvms","getCvms","choices","cvm","id","name","status","selectedCvm","inquirer","getCvmAttestation","appId","response","apiClient","API_ENDPOINTS","cvmAttestationResponseSchema","validationError","error","resizeCvm","vcpu","memory","diskSize","allowRestart","resizePayload","chalk","listCommand","Command","options","spinner","logger","cvms","getCvms","cvm","CLOUD_URL","error","Command","chalk","resolveCvmAppId","appId","selectedCvm","selectCvm","checkCvmExists","getCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","spinner","logger","cvm","getCvmByAppId","chalk","CLOUD_URL","error","Command","startCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","startCvm","tableData","CLOUD_URL","error","Command","stopCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","stopCvm","tableData","CLOUD_URL","error","Command","restartCommand","Command","appId","resolvedAppId","resolveCvmAppId","spinner","logger","response","restartCvm","tableData","CLOUD_URL","error","Command","chalk","attestationCommand","Command","appId","options","resolvedAppId","checkCvmExists","logger","selectedCvm","selectCvm","spinner","attestationData","getCvmAttestation","summaryData","cert","index","certData","tcbBasicInfo","maxEntriesToShow","entries","entry","error","Command","z","getTeepods","response","apiClient","API_ENDPOINTS","teepodResponseSchema","error","encryptEnvVars","fs","path","inquirer","fs","parseEnv","envs","envFile","envVars","env","key","value","envFileContent","line","valueParts","commentIndex","createCommand","Command","DEFAULT_VCPU","DEFAULT_MEMORY","DEFAULT_DISK_SIZE","options","name","inquirer","input","composeFileName","detectFileInCurrentDir","promptForFile","composePath","path","fs","logger","composeString","deleteSimulatorEndpointEnv","envs","parseEnv","error","shouldSkip","envVars","vcpu","memory","diskSize","teepodsSpinner","teepods","getTeepods","selectedTeepod","pod","selectedImage","image","vmConfig","spinner","pubkey","getPubkeyFromCvm","encryptSpinner","encrypted_env","encryptEnvVars","createSpinner","response","createCvm","tableData","CLOUD_URL","Command","inquirer","deleteCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","confirm","inquirer","logger","spinner","success","deleteCvm","error","Command","fs","encryptEnvVars","upgradeCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","spinner","logger","currentCvm","getCvmByAppId","composeFileName","detectFileInCurrentDir","promptForFile","composeString","fs","error","deleteSimulatorEndpointEnv","encrypted_env","envs","parseEnv","encryptEnvVars","vm_config","upgradeSpinner","response","upgradeCvm","CLOUD_URL","Command","inquirer","chalk","resizeCommand","Command","appId","options","resolvedAppId","resolveCvmAppId","cvm","getCvmByAppId","vcpu","memory","diskSize","allowRestart","inquirer","input","num","confirmMessage","logger","chalk","confirm","spinner","resizeCvm","CLOUD_URL","error","cvmsCommand","Command","attestationCommand","createCommand","deleteCommand","getCommand","listCommand","startCommand","stopCommand","resizeCommand","restartCommand","upgradeCommand","Command","execSync","os","openBrowser","url","platform","execSync","logger","error","sleep","ms","resolve","joinCommand","Command","inviteUrl","spinner","logo","Command","jupyterCompose","httpbinCompose","demoTemplates","encryptEnvVars","inquirer","crypto","demoCommands","Command","getApiKey","logger","spinner","userInfo","getUserInfo","templates","demoTemplates","selectedTemplate","inquirer","t","templateContent","token","crypto","envVars","parseEnv","cvmName","input","vmConfig","DEFAULT_IMAGE","pubkey","getPubkeyFromCvm","encrypted_env","encryptEnvVars","createSpinner","response","createCvm","tableData","CLOUD_URL","error","main","Command","logo","authCommands","cvmsCommand","dockerCommands","simulatorCommands","demoCommands","joinCommand","error","logger"]}