added create and delete cli

This commit is contained in:
Dillon DuPont
2025-11-11 12:11:48 -05:00
parent be8bb62bb4
commit f2dfe865fd
3 changed files with 109 additions and 4 deletions
+5
View File
@@ -24,6 +24,11 @@ bun run ./index.ts -- --help
- **VMs**
- `cua vm list`
- `cua vm create --os OS --configuration SIZE --region REGION` creates a new VM
- OS: `linux`, `windows`, `macos`
- SIZE: `small`, `medium`, `large`
- REGION: `north-america`, `europe`, `asia-pacific`, `south-america`
- `cua vm delete NAME` deletes a VM
- `cua vm start NAME`
- `cua vm stop NAME`
- `cua vm restart NAME`
+100
View File
@@ -32,6 +32,106 @@ export function registerVmCommands(y: Argv) {
printVmList(data);
}
)
.command(
"create",
"Create a new VM",
(y) => y
.option("os", {
type: "string",
choices: ["linux", "windows", "macos"],
demandOption: true,
describe: "Operating system"
})
.option("configuration", {
type: "string",
choices: ["small", "medium", "large"],
demandOption: true,
describe: "VM size configuration"
})
.option("region", {
type: "string",
choices: ["north-america", "europe", "asia-pacific", "south-america"],
demandOption: true,
describe: "VM region"
}),
async (argv: Record<string, unknown>) => {
const token = await ensureApiKeyInteractive();
const { os, configuration, region } = argv as { os: string; configuration: string; region: string };
const res = await http("/v1/vms", {
token,
method: "POST",
body: { os, configuration, region }
});
if (res.status === 401) {
clearApiKey();
console.error("Unauthorized. Try 'cua auth login' again.");
process.exit(1);
}
if (res.status === 400) {
console.error("Invalid request or unsupported configuration");
process.exit(1);
}
if (res.status === 500) {
console.error("Internal server error");
process.exit(1);
}
if (res.status === 200) {
// VM ready immediately
const data = await res.json() as { status: string; name: string; password: string; host: string };
console.log(`VM created and ready: ${data.name}`);
console.log(`Password: ${data.password}`);
console.log(`Host: ${data.host}`);
return;
}
if (res.status === 202) {
// VM provisioning started
const data = await res.json() as { status: string; name: string; job_id: string };
console.log(`VM provisioning started: ${data.name}`);
console.log(`Job ID: ${data.job_id}`);
console.log("Use 'cua vm list' to monitor provisioning progress");
return;
}
console.error(`Unexpected status: ${res.status}`);
process.exit(1);
}
)
.command(
"delete <name>",
"Delete a VM",
(y) => y.positional("name", { type: "string", describe: "VM name" }),
async (argv: Record<string, unknown>) => {
const token = await ensureApiKeyInteractive();
const name = String((argv as any).name);
const res = await http(`/v1/vms/${encodeURIComponent(name)}`, { token, method: "DELETE" });
if (res.status === 202) {
const body = await res.json().catch(() => ({})) as { status?: string };
console.log(`VM deletion initiated: ${body.status ?? "deleting"}`);
return;
}
if (res.status === 404) {
console.error("VM not found or not owned by you");
process.exit(1);
}
if (res.status === 401) {
clearApiKey();
console.error("Unauthorized. Try 'cua auth login' again.");
process.exit(1);
}
console.error(`Unexpected status: ${res.status}`);
process.exit(1);
}
)
.command(
"start <name>",
"Start a VM",
+4 -4
View File
@@ -10,12 +10,12 @@ export async function writeEnvFile(cwd: string, key: string) {
}
export type VmStatus = "pending" | "running" | "stopped" | "terminated" | "failed";
export type VmItem = { name: string; password: string; status: VmStatus };
export type VmItem = { name: string; password: string; status: VmStatus; host?: string };
export function printVmList(items: VmItem[]) {
const rows: string[][] = [["NAME", "STATUS", "PASSWORD"], ...items.map(v => [v.name, String(v.status), v.password])];
const widths: number[] = [0, 0, 0];
for (const r of rows) for (let i = 0; i < 3; i++) widths[i] = Math.max(widths[i] ?? 0, (r[i] ?? "").length);
const rows: string[][] = [["NAME", "STATUS", "PASSWORD", "HOST"], ...items.map(v => [v.name, String(v.status), v.password, v.host || ""])];
const widths: number[] = [0, 0, 0, 0];
for (const r of rows) for (let i = 0; i < 4; i++) widths[i] = Math.max(widths[i] ?? 0, (r[i] ?? "").length);
for (const r of rows) console.log(r.map((c, i) => (c ?? "").padEnd(widths[i] ?? 0)).join(" "));
if (items.length === 0) console.log("No VMs found");
}