UNPKG

sesterce-cli

Version:

A powerful command-line interface tool for managing Sesterce Cloud services. Sesterce CLI provides easy access to GPU cloud instances, AI inference services, container registries, and SSH key management directly from your terminal.

271 lines (253 loc) 11.5 kB
import { InferenceInstance, InferenceInstanceFeature, InferenceInstanceStatus, } from "@/modules/ai-inference/domain/inference-instance"; import { getInstanceDetails } from "@/modules/ai-inference/use-cases/get-instance-details"; import { listInferenceInstances } from "@/modules/ai-inference/use-cases/list-instances"; import { search } from "@inquirer/prompts"; import chalk from "chalk"; import { Command } from "commander"; import figlet from "figlet"; const getStatusColor = (status: InferenceInstanceStatus) => { switch (status) { case "ACTIVE": return chalk.hex("#50FA7B"); // Green case "PENDING": case "DEPLOYING": return chalk.hex("#FFB86C"); // Orange case "ERROR": case "FAILED": return chalk.hex("#FF5555"); // Red case "DISABLED": case "DELETED": case "DELETING": return chalk.hex("#6272A4"); // Gray case "PARTIALLYDEPLOYED": return chalk.hex("#FF79C6"); // Pink default: return chalk.white; } }; const printInstance = (instance: InferenceInstance) => { return `${instance.name} (${instance.features.join(", ")}) | ${instance.address} | ${instance.status} | ${instance.hourlyPrice.toFixed(2)}`; }; export function createAIInferenceInstanceDetailsCommand( aiInferenceInstanceCommand: Command ) { aiInferenceInstanceCommand .command("details") .description("Get details of a launched instance in Sesterce AI Inference") .option( "-i, --instance-id <instanceId>", "The ID of the instance to get details of" ) .action(async (args) => { let instanceId = args.instanceId; if (!instanceId) { console.log("Loading inference instances..."); const result = await listInferenceInstances.execute(); if (result.isLeft()) { console.error(result.value.message); return; } const instances = result.value; if (instances.length === 0) { console.log("No instances found"); return; } const instance = await search({ message: "Select an instance to get details for", source: async (input) => { if (!input) { return instances.map((instance) => ({ name: printInstance(instance), value: instance, })); } return instances .filter( (instance) => instance.name.toLowerCase().includes(input.toLowerCase()) || instance.address .toLowerCase() .includes(input.toLowerCase()) || instance.features.includes( input.toLowerCase() as InferenceInstanceFeature ) || instance.status.toLowerCase().includes(input.toLowerCase()) || instance.hourlyPrice.toFixed(2).includes(input) ) .map((instance) => ({ name: printInstance(instance), value: instance, })); }, }); instanceId = instance._id; } const result = await getInstanceDetails.execute(instanceId); if (result.isLeft()) { console.error(result.value.message); return; } const instance = result.value; // Header with instance name console.log("\n" + "=".repeat(80)); console.log( chalk.hex("#21C65D")( figlet.textSync(instance.name, { font: "Standard" }) ) ); console.log("=".repeat(80) + "\n"); // Basic Information Section console.log(chalk.hex("#FF6B6B")(chalk.bold("📋 BASIC INFORMATION"))); console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("ID:")} ${chalk.white(instance._id)}${" ".repeat(78 - 4 - instance._id.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Name:")} ${chalk.white(instance.name)}${" ".repeat(78 - 6 - instance.name.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Status:")} ${getStatusColor(instance.status)(instance.status)}${" ".repeat(78 - 8 - instance.status.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Address:")} ${chalk.cyan(instance.address)}${" ".repeat(78 - 9 - instance.address.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Port:")} ${chalk.white(instance.containerPort)}${" ".repeat(78 - 5 - instance.containerPort.toString().length)}${chalk.hex("#4ECDC4")("│")}` ); console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n")); // Features and Pricing Section console.log(chalk.hex("#FF6B6B")(chalk.bold("🚀 FEATURES & PRICING"))); console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Features:")} ${instance.features.map((f) => chalk.hex("#FFE66D")(f)).join(", ")}${" ".repeat(78 - 10 - instance.features.join(", ").length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Hardware:")} ${chalk.white(instance.hardwareName)}${" ".repeat(78 - 9 - instance.hardwareName.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Hourly Price:")} ${chalk.hex("#50FA7B")(`$${instance.hourlyPrice.toFixed(2)}`)}${" ".repeat(78 - 13 - instance.hourlyPrice.toFixed(2).length - 1)}${chalk.hex("#4ECDC4")("│")}` ); if (instance.description) { console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Description:")} ${chalk.white(instance.description)}${" ".repeat(78 - 12 - instance.description.length)}${chalk.hex("#4ECDC4")("│")}` ); } console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n")); // Container Information Section console.log(chalk.hex("#FF6B6B")(chalk.bold("🐳 CONTAINER INFORMATION"))); instance.containers.forEach((container, index) => { console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold(`Container ${index + 1}:`)}${" ".repeat(78 - 12)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Region ID:")} ${chalk.white(container.regionId)}${" ".repeat(78 - 11 - container.regionId.toString().length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Scale:")} ${chalk.white(`${container.scale.min}-${container.scale.max}`)}${" ".repeat(78 - 6 - `${container.scale.min}-${container.scale.max}`.length)}${chalk.hex("#4ECDC4")("│")}` ); // Triggers const triggers = container.scale.triggers || {}; const triggerEntries = []; if (triggers.cpu) triggerEntries.push( `CPU: ${chalk.yellow(triggers.cpu.threshold + "%")}` ); if (triggers.gpuMemory) triggerEntries.push( `GPU Memory: ${chalk.yellow(triggers.gpuMemory.threshold + "%")}` ); if (triggers.gpuUtilization) triggerEntries.push( `GPU Util: ${chalk.yellow(triggers.gpuUtilization.threshold + "%")}` ); if (triggers.memory) triggerEntries.push( `RAM: ${chalk.yellow(triggers.memory.threshold + "%")}` ); if (triggers.http) triggerEntries.push( `HTTP: ${chalk.yellow(triggers.http.rate + "/s (" + triggers.http.window + "s)")}` ); if (triggerEntries.length > 0) { console.log( chalk.hex("#4ECDC4")("│") + ` Triggers: ${triggerEntries.join(", ")}${" ".repeat(78 - 10 - triggerEntries.join(", ").length)}${chalk.hex("#4ECDC4")("│")}` ); } console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Deploy Status:")} ${chalk.hex("#50FA7B")(`${container.deployStatus.ready}/${container.deployStatus.total}`)}${" ".repeat(78 - 14 - `${container.deployStatus.ready}/${container.deployStatus.total}`.length)}${chalk.hex("#4ECDC4")("│")}` ); if (container.errorMessage) { console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Error:")} ${chalk.red(container.errorMessage)}${" ".repeat(78 - 6 - container.errorMessage.length)}${chalk.hex("#4ECDC4")("│")}` ); } console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘")); }); // Environment Variables Section if (Object.keys(instance.envs).length > 0) { console.log( chalk.hex("#FF6B6B")(chalk.bold("🔧 ENVIRONMENT VARIABLES")) ); console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); Object.entries(instance.envs).forEach(([key, value]) => { const displayValue = value.length > 60 ? value.substring(0, 57) + "..." : value; console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold(key)}: ${chalk.white(displayValue)}${" ".repeat(78 - key.length - 2 - displayValue.length)}${chalk.hex("#4ECDC4")("│")}` ); }); console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n")); } // Startup Command Section if (instance.startupCommand) { console.log(chalk.hex("#FF6B6B")(chalk.bold("⚡ STARTUP COMMAND"))); console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.white(instance.startupCommand)}${" ".repeat(78 - instance.startupCommand.length)}${chalk.hex("#4ECDC4")("│")}` ); console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n")); } // Timestamps Section console.log(chalk.hex("#FF6B6B")(chalk.bold("⏰ TIMESTAMPS"))); console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐")); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Created:")} ${chalk.white(new Date(instance.createdAt).toLocaleString())}${" ".repeat(78 - 9 - new Date(instance.createdAt).toLocaleString().length)}${chalk.hex("#4ECDC4")("│")}` ); console.log( chalk.hex("#4ECDC4")("│") + ` ${chalk.bold("Updated:")} ${chalk.white(new Date(instance.updatedAt).toLocaleString())}${" ".repeat(78 - 9 - new Date(instance.updatedAt).toLocaleString().length)}${chalk.hex("#4ECDC4")("│")}` ); console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n")); // Footer console.log(chalk.hex("#21C65D")("=".repeat(80))); console.log( chalk.hex("#21C65D")( chalk.bold("✨ Instance details displayed successfully!") ) ); console.log(chalk.hex("#21C65D")("=".repeat(80)) + "\n"); }); }