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
text/typescript
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");
});
}