@ghalex/kvbox 0.0.5 → 0.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/kvbox.js CHANGED
@@ -63,7 +63,7 @@ function versionOf(srcFileUrl, injected) {
63
63
  }
64
64
 
65
65
  // src/version.ts
66
- var VERSION = versionOf(import.meta.url, true ? "0.0.5" : void 0);
66
+ var VERSION = versionOf(import.meta.url, true ? "0.0.6" : void 0);
67
67
 
68
68
  // src/commands/vm/index.ts
69
69
  import { Command as Command7 } from "commander";
@@ -95,9 +95,9 @@ import { z } from "zod";
95
95
 
96
96
  // ../shared/src/sizes.ts
97
97
  var SIZES = {
98
- s: { vcpu: 2, memMib: 4096 },
99
- m: { vcpu: 4, memMib: 8192 },
100
- l: { vcpu: 8, memMib: 16384 }
98
+ s: { vcpu: 2, memMib: 4096, diskGib: 8 },
99
+ m: { vcpu: 4, memMib: 8192, diskGib: 16 },
100
+ l: { vcpu: 8, memMib: 16384, diskGib: 32 }
101
101
  };
102
102
  var SIZE_NAMES = Object.keys(SIZES);
103
103
 
@@ -111,9 +111,11 @@ var MachineSchema = z.object({
111
111
  vcpu: z.number().int(),
112
112
  memMib: z.number().int(),
113
113
  diskBytes: z.number().int(),
114
- // size of the disk as the guest sees it
114
+ // the box's own writable disk, as the guest sees it
115
115
  diskUsedBytes: z.number().int(),
116
- // what the sparse disk file really occupies on the host
116
+ // what that sparse file really occupies on the host
117
+ base: z.string().nullable(),
118
+ // base image version the box runs on (null: pre-overlay box with its own copy)
117
119
  createdAt: z.string(),
118
120
  source: z.string(),
119
121
  // "base" or "snapshot:<name>"
@@ -172,12 +174,17 @@ function paths(home = kvboxHome()) {
172
174
  firecracker: join(home, "bin", "firecracker"),
173
175
  assets: join(home, "assets"),
174
176
  kernel: join(home, "assets", "vmlinux"),
177
+ /** Symlink to the current base image, assets/rootfs-<version>.ext4; boxes keep using the version they were made from. */
175
178
  rootfs: join(home, "assets", "rootfs.ext4"),
179
+ baseImage: (version) => join(home, "assets", `rootfs-${version}.ext4`),
176
180
  machines: join(home, "machines"),
177
181
  snapshots: join(home, "snapshots"),
178
182
  machine: (name) => ({
179
183
  dir: join(home, "machines", name),
180
184
  meta: join(home, "machines", name, "meta.json"),
185
+ /** The box's writable layer, stacked on the read-only base image inside the guest. */
186
+ overlay: join(home, "machines", name, "overlay.ext4"),
187
+ /** Boxes made before overlays: a full copy of the base image. Kept bootable, never created anymore. */
181
188
  disk: join(home, "machines", name, "disk.ext4"),
182
189
  sock: join(home, "machines", name, "fc.sock"),
183
190
  log: join(home, "machines", name, "fc.log")
@@ -372,7 +379,7 @@ var lsCommand = new Command2("ls").description("list boxes with status and IP").
372
379
  cpu: `${b.vcpu} vCPU`,
373
380
  ram: gb(b.memMib * 1024 ** 2),
374
381
  disk: `${gb(b.diskBytes)} (${gb(b.diskUsedBytes)} used)`,
375
- source: b.source,
382
+ source: b.base !== null && b.source === "base" ? `base ${b.base}` : b.source,
376
383
  created: b.createdAt.replace("T", " ").slice(0, 16)
377
384
  }))
378
385
  );
package/dist/kvbox.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/output.ts","../src/program.ts","../../shared/src/version.ts","../src/version.ts","../src/commands/vm/index.ts","../src/commands/vm/connect.ts","../../shared/src/errors.ts","../src/client.ts","../../shared/src/api.ts","../../shared/src/sizes.ts","../../shared/src/paths.ts","../src/commands/vm/ls.ts","../src/commands/vm/new.ts","../src/commands/vm/rm.ts","../src/commands/vm/start.ts","../src/commands/vm/stop.ts","../src/commands/server/index.ts","../src/commands/server/start.ts","../src/commands/server/status.ts","../src/commands/server/stop.ts","../src/commands/snapshot/index.ts","../src/commands/snapshot/ls.ts","../src/commands/snapshot/rm.ts","../src/commands/snapshot/save.ts","../src/index.ts"],"sourcesContent":["/** Printing: tables for humans, `--json` for agents, colors only on a TTY. */\nimport pc from \"picocolors\";\n\nexport const color = pc.createColors(process.stdout.isTTY === true && !process.env[\"NO_COLOR\"]);\n\nexport function json(value: unknown): void {\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\");\n}\n\nexport function table(rows: Record<string, string | number | null | undefined>[], columns?: string[]): void {\n if (rows.length === 0) return;\n const cols = columns ?? Object.keys(rows[0]!);\n const cells = rows.map((r) => cols.map((c) => String(r[c] ?? \"\")));\n const widths = cols.map((c, i) => Math.max(c.length, ...cells.map((r) => r[i]!.length)));\n const line = (parts: string[]) => parts.map((p, i) => p.padEnd(widths[i]!)).join(\" \").trimEnd();\n process.stdout.write(color.dim(line(cols.map((c) => c.toUpperCase()))) + \"\\n\");\n for (const row of cells) process.stdout.write(line(row) + \"\\n\");\n}\n\nexport function info(msg: string): void {\n process.stderr.write(msg + \"\\n\");\n}\n\nexport function warn(msg: string): void {\n process.stderr.write(color.yellow(msg) + \"\\n\");\n}\n\nexport function notImplemented(command: string): never {\n process.stderr.write(color.yellow(`kvbox ${command}: not implemented yet\\n`));\n process.exit(2);\n}\n\n/** y/N prompt on a TTY; requires `-y` otherwise (boxd's rule for destructive commands). */\nexport async function confirm(question: string, yes: boolean): Promise<boolean> {\n if (yes) return true;\n if (!process.stdin.isTTY) {\n warn(\"refusing without -y when stdin is not a terminal\");\n return false;\n }\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n try {\n const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\n/** Bytes for humans: 4 GiB -> \"4 GB\", 3.4 GiB -> \"3.4 GB\", under 1 GiB -> \"640 MB\". */\nexport function gb(bytes: number): string {\n const g = bytes / 1024 ** 3;\n if (g >= 1) return `${Number.isInteger(g) ? g : g.toFixed(1)} GB`;\n return `${Math.round(bytes / 1024 ** 2)} MB`;\n}\n","/** Builds the commander tree. Importable without side effects (tests); src/index.ts runs it. */\nimport { Command } from \"commander\";\nimport { VERSION } from \"./version.js\";\nimport { vmAliases, vmCommand } from \"./commands/vm/index.js\";\nimport { serverCommand } from \"./commands/server/index.js\";\nimport { snapshotCommand } from \"./commands/snapshot/index.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"kvbox\")\n .description(\"self-hosted Firecracker microVMs with Docker-like ergonomics\")\n .version(VERSION, \"-v, --version\")\n .option(\"--host <name>\", \"target a configured remote host (M2)\")\n .showHelpAfterError()\n .enablePositionalOptions();\n\n program.addCommand(vmCommand);\n program.addCommand(snapshotCommand);\n program.addCommand(serverCommand);\n // Top-level shortcuts: the same Command objects as under `vm`.\n for (const cmd of vmAliases) program.addCommand(cmd);\n\n return program;\n}\n","/**\n * Each binary's version comes from its own package.json: tsup injects\n * `__KVBOX_VERSION__` at build time; the dev path (tsx) reads the file.\n * Usage in a package: `versionOf(import.meta.url)` from its `src/version.ts`.\n */\nimport { createRequire } from \"node:module\";\n\nexport function versionOf(srcFileUrl: string, injected?: string): string {\n if (typeof injected === \"string\") return injected;\n try {\n const require = createRequire(srcFileUrl);\n return (require(\"../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0-dev\";\n }\n}\n","import { versionOf } from \"@kvbox/shared/version\";\n\ndeclare const __KVBOX_VERSION__: string | undefined;\n\nexport const VERSION: string = versionOf(import.meta.url, typeof __KVBOX_VERSION__ === \"string\" ? __KVBOX_VERSION__ : undefined);\n","import { Command } from \"commander\";\nimport { connectCommand } from \"./connect.js\";\nimport { lsCommand } from \"./ls.js\";\nimport { newCommand } from \"./new.js\";\nimport { rmCommand } from \"./rm.js\";\nimport { startCommand } from \"./start.js\";\nimport { stopCommand } from \"./stop.js\";\n\nexport const vmCommand = new Command(\"vm\")\n .enablePositionalOptions()\n .description(\"manage boxes (each one is a Firecracker microVM)\")\n .addCommand(newCommand)\n .addCommand(lsCommand)\n .addCommand(connectCommand)\n .addCommand(stopCommand)\n .addCommand(startCommand)\n .addCommand(rmCommand);\n\n/** The same Command objects, added again at the top level so they cannot drift. */\nexport const vmAliases = [newCommand, lsCommand, connectCommand, stopCommand, startCommand, rmCommand];\n","import { spawnSync } from \"node:child_process\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs } from \"../../client.js\";\n\n/** kvbox vm connect <name> [-- cmd...] — ssh kvbox@<ip> with the kvbox key; a shell, or run a command */\nexport const connectCommand = new Command(\"connect\")\n .description(\"open a shell in a box over SSH (or run a command: kvbox connect <name> -- <cmd>)\")\n .argument(\"<name>\", \"box name\")\n .argument(\"[cmd...]\", \"command to run instead of a shell\")\n .passThroughOptions()\n .action(async (name: string, cmdArgs: string[], _opts: unknown, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n let ip: string;\n try {\n const box = (await client.listMachines()).find((b) => b.name === name);\n if (!box) throw new KvboxError(`box ${name}: not found (kvbox ls)`);\n if (box.status !== \"running\") throw new KvboxError(`box ${name} is ${box.status}`);\n ip = box.ip;\n } finally {\n await client.close();\n }\n const res = spawnSync(\"ssh\", [...sshArgs(ip), ...cmdArgs], { stdio: \"inherit\" });\n if (res.error) throw new KvboxError(`could not run ssh: ${res.error.message}`);\n process.exit(res.status ?? 1);\n });\n","/** Errors with an exit code; the entry point prints `message` and exits with `exitCode`. */\nexport class KvboxError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = 1,\n ) {\n super(message);\n this.name = \"KvboxError\";\n }\n}\n\nexport class NotImplementedError extends KvboxError {\n constructor(what: string) {\n super(`${what}: not implemented yet`, 2);\n this.name = \"NotImplementedError\";\n }\n}\n\n/** The named box/snapshot/host does not exist: HTTP 404, exit 1. */\nexport class NotFoundError extends KvboxError {\n constructor(what: string) {\n super(`${what}: not found`, 1);\n this.name = \"NotFoundError\";\n }\n}\n","/**\n * ServerClient: one method per route of the kvbox API, over undici.\n * Target resolution: `--host` -> configured hosts (M2) -> local Unix socket.\n * Auto-starting the local server from every command when nothing listens is #17;\n * `startLocalServer` below is the piece it will reuse.\n */\nimport { spawn } from \"node:child_process\";\nimport { openSync } from \"node:fs\";\nimport { mkdir, stat } from \"node:fs/promises\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\nimport { Agent, request, type Dispatcher } from \"undici\";\nimport { z } from \"zod\";\nimport {\n ApiErrorSchema,\n CapacitySchema,\n HealthSchema,\n MachineSchema,\n SnapshotSchema,\n type CreateMachineRequest,\n type CreateSnapshotRequest,\n} from \"@kvbox/shared/api\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { paths, type Paths } from \"@kvbox/shared/paths\";\n\nexport type Target = { kind: \"local\"; socketPath: string } | { kind: \"remote\"; name: string; url: string };\n\nexport function resolveTarget(hostFlag?: string): Target {\n if (hostFlag) {\n throw new KvboxError(`--host ${hostFlag}: remote hosts arrive in M2`);\n }\n return { kind: \"local\", socketPath: paths().serverSock };\n}\n\nexport interface ClientOptions {\n /** Spawn `kvbox-server` when the local socket does not answer (default true; the start probe turns it off). */\n autoStart?: boolean;\n}\n\nexport class ServerClient {\n private readonly dispatcher: Dispatcher;\n private readonly base: string;\n private readonly autoStart: boolean;\n private startedOnce = false;\n\n constructor(\n readonly target: Target,\n opts: ClientOptions = {},\n ) {\n this.autoStart = opts.autoStart ?? true;\n if (target.kind === \"local\") {\n this.dispatcher = new Agent({ connect: { socketPath: target.socketPath } });\n this.base = \"http://kvbox\";\n } else {\n this.dispatcher = new Agent();\n this.base = target.url;\n }\n }\n\n private async call<T>(\n method: \"GET\" | \"POST\" | \"DELETE\",\n path: string,\n schema: z.ZodType<T>,\n body?: unknown,\n ): Promise<T> {\n let res;\n try {\n res = await request(this.base + path, {\n dispatcher: this.dispatcher,\n method,\n headers: body === undefined ? {} : { \"content-type\": \"application/json\" },\n body: body === undefined ? null : JSON.stringify(body),\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code ?? (err as Error).cause;\n if (this.target.kind === \"local\") {\n // Nothing listens locally: start the daemon once and retry (architecture: \"auto-start\").\n if (this.autoStart && !this.startedOnce) {\n this.startedOnce = true;\n await startLocalServer(paths(), 5000);\n return this.call(method, path, schema, body);\n }\n throw new KvboxError(`kvbox-server is not running (${String(code)}); start it with: kvbox server start`);\n }\n throw new KvboxError(`cannot reach ${this.target.name}: ${String(code)}`);\n }\n const text = await res.body.text();\n if (res.statusCode >= 300) {\n const parsed = ApiErrorSchema.safeParse(text ? JSON.parse(text) : {});\n const msg = parsed.success ? parsed.data.error : `${res.statusCode} ${text}`;\n throw new KvboxError(msg, res.statusCode === 501 ? 2 : 1);\n }\n return schema.parse(text ? JSON.parse(text) : undefined);\n }\n\n health() {\n return this.call(\"GET\", \"/health\", HealthSchema);\n }\n\n capacity() {\n return this.call(\"GET\", \"/capacity\", CapacitySchema);\n }\n\n listMachines() {\n return this.call(\"GET\", \"/machines\", z.array(MachineSchema));\n }\n\n createMachine(req: CreateMachineRequest) {\n return this.call(\"POST\", \"/machines\", MachineSchema, req);\n }\n\n stopMachine(name: string) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/stop`, MachineSchema);\n }\n\n startMachine(name: string) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/start`, MachineSchema);\n }\n\n deleteMachine(name: string) {\n return this.call(\"DELETE\", `/machines/${encodeURIComponent(name)}`, z.undefined());\n }\n\n listSnapshots() {\n return this.call(\"GET\", \"/snapshots\", z.array(SnapshotSchema));\n }\n\n createSnapshot(req: CreateSnapshotRequest) {\n return this.call(\"POST\", \"/snapshots\", SnapshotSchema, req);\n }\n\n deleteSnapshot(name: string) {\n return this.call(\"DELETE\", `/snapshots/${encodeURIComponent(name)}`, z.undefined());\n }\n\n async close() {\n await this.dispatcher.close();\n }\n}\n\n/** Build a client from the global `--host` option of the root command. */\nexport function clientFor(opts: { host?: string }, client: ClientOptions = {}): ServerClient {\n return new ServerClient(resolveTarget(opts.host), client);\n}\n\n/**\n * `ssh` argv for a box. Host keys are per box and IPs get reused, so no known_hosts;\n * SetEnv pins the locale because the image only ships C.UTF-8 (#24).\n */\nexport function sshArgs(ip: string, keyPath: string = paths().sshKey): string[] {\n return [\n \"-i\", keyPath,\n \"-o\", \"StrictHostKeyChecking=no\",\n \"-o\", \"UserKnownHostsFile=/dev/null\",\n \"-o\", \"LogLevel=ERROR\",\n \"-o\", \"SetEnv=LC_ALL=C.UTF-8\",\n `kvbox@${ip}`,\n ];\n}\n\nexport const NOT_A_HOST_HINT =\n \"kvbox-server is not installed, so this machine is not a kvbox host. \" +\n \"Set it up with install-server.sh, or point the CLI at a remote host (M2: kvbox host add).\";\n\n/**\n * Spawn `kvbox-server start` from PATH, detached, stdio to ~/.kvbox/server.log,\n * and resolve once its socket accepts a /health call (or reject after `timeoutMs`).\n */\nexport async function startLocalServer(p: Paths = paths(), timeoutMs = 5000): Promise<{ pid: number; socketPath: string }> {\n await mkdir(p.home, { recursive: true });\n const log = openSync(p.serverLog, \"a\");\n const child = spawn(\"kvbox-server\", [\"start\"], { detached: true, stdio: [\"ignore\", log, log] });\n\n const failed = new Promise<never>((_, reject) => {\n child.once(\"error\", (err: NodeJS.ErrnoException) => {\n reject(new KvboxError(err.code === \"ENOENT\" ? NOT_A_HOST_HINT : `could not start kvbox-server: ${err.message}`));\n });\n child.once(\"exit\", (code) => {\n reject(new KvboxError(`kvbox-server exited with code ${String(code)} before listening; see ${p.serverLog}`));\n });\n });\n\n const ready = (async () => {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await stat(p.serverSock).then(() => true, () => false)) {\n const probe = new ServerClient({ kind: \"local\", socketPath: p.serverSock }, { autoStart: false });\n try {\n await probe.health();\n return;\n } catch {\n // socket exists but not serving yet\n } finally {\n await probe.close();\n }\n }\n await sleep(100);\n }\n throw new KvboxError(`kvbox-server did not start within ${timeoutMs / 1000}s; see ${p.serverLog}`);\n })();\n\n await Promise.race([ready, failed]);\n child.removeAllListeners(\"exit\");\n child.unref();\n return { pid: child.pid ?? -1, socketPath: p.serverSock };\n}\n","/**\n * Wire shapes of the kvbox HTTP API, shared by the client (src/cli) and the\n * server (src/server). Validated with zod on both sides because the client\n * may be talking to an older or newer server.\n */\nimport { z } from \"zod\";\nimport { SIZE_NAMES } from \"./sizes.js\";\n\nexport const SizeSchema = z.enum(SIZE_NAMES as [string, ...string[]]);\n\nexport const MachineSchema = z.object({\n name: z.string(),\n ip: z.string(),\n mac: z.string(),\n pid: z.number().int().nullable(),\n vcpu: z.number().int(),\n memMib: z.number().int(),\n diskBytes: z.number().int(), // size of the disk as the guest sees it\n diskUsedBytes: z.number().int(), // what the sparse disk file really occupies on the host\n createdAt: z.string(),\n source: z.string(), // \"base\" or \"snapshot:<name>\"\n status: z.enum([\"running\", \"stopped\"]),\n});\nexport type Machine = z.infer<typeof MachineSchema>;\n\nexport const CreateMachineRequest = z.object({\n name: z.string().optional(),\n size: SizeSchema.optional(),\n from: z.string().optional(),\n force: z.boolean().optional(),\n});\nexport type CreateMachineRequest = z.infer<typeof CreateMachineRequest>;\n\nexport const SnapshotSchema = z.object({\n name: z.string(),\n source: z.string(),\n vcpu: z.number().int(),\n memMib: z.number().int(),\n createdAt: z.string(),\n});\nexport type Snapshot = z.infer<typeof SnapshotSchema>;\n\nexport const CreateSnapshotRequest = z.object({\n box: z.string(),\n name: z.string(),\n});\nexport type CreateSnapshotRequest = z.infer<typeof CreateSnapshotRequest>;\n\nexport const CapacitySchema = z.object({\n hostMemMib: z.number().int(),\n hostCores: z.number().int(),\n reservedMemMib: z.number().int(),\n reservedVcpu: z.number().int(),\n running: z.number().int(),\n});\nexport type Capacity = z.infer<typeof CapacitySchema>;\n\nexport const HealthSchema = z.object({\n ok: z.literal(true),\n version: z.string(),\n pid: z.number().int(),\n});\nexport type Health = z.infer<typeof HealthSchema>;\n\nexport const ApiErrorSchema = z.object({\n error: z.string(),\n});\n","/** Fixed box sizes. Firecracker backs guest memory lazily, so a box only costs what the guest touches. */\nexport const SIZES = {\n s: { vcpu: 2, memMib: 4096 },\n m: { vcpu: 4, memMib: 8192 },\n l: { vcpu: 8, memMib: 16384 },\n} as const;\n\nexport type SizeName = keyof typeof SIZES;\nexport const SIZE_NAMES = Object.keys(SIZES) as SizeName[];\nexport const DEFAULT_SIZE: SizeName = \"s\";\n\nexport function isSizeName(value: string): value is SizeName {\n return value in SIZES;\n}\n","/**\n * Host state layout. The filesystem is the database and `~/.kvbox` is its root.\n * This module is dependency-free so both the CLI (socket path, hosts.json)\n * and core (everything else) can use it without crossing the layer boundary.\n *\n * `KVBOX_HOME` overrides the root, mainly for tests.\n */\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport function kvboxHome(): string {\n return process.env[\"KVBOX_HOME\"] ?? join(homedir(), \".kvbox\");\n}\n\nexport function paths(home: string = kvboxHome()) {\n return {\n home,\n config: join(home, \"config.json\"),\n serverSock: join(home, \"server.sock\"),\n serverPid: join(home, \"server.pid\"),\n serverLog: join(home, \"server.log\"),\n hosts: join(home, \"hosts.json\"),\n ssh: join(home, \"ssh\"),\n sshKey: join(home, \"ssh\", \"id_ed25519\"),\n bin: join(home, \"bin\"),\n firecracker: join(home, \"bin\", \"firecracker\"),\n assets: join(home, \"assets\"),\n kernel: join(home, \"assets\", \"vmlinux\"),\n rootfs: join(home, \"assets\", \"rootfs.ext4\"),\n machines: join(home, \"machines\"),\n snapshots: join(home, \"snapshots\"),\n machine: (name: string) => ({\n dir: join(home, \"machines\", name),\n meta: join(home, \"machines\", name, \"meta.json\"),\n disk: join(home, \"machines\", name, \"disk.ext4\"),\n sock: join(home, \"machines\", name, \"fc.sock\"),\n log: join(home, \"machines\", name, \"fc.log\"),\n }),\n snapshot: (name: string) => ({\n dir: join(home, \"snapshots\", name),\n meta: join(home, \"snapshots\", name, \"meta.json\"),\n vmstate: join(home, \"snapshots\", name, \"vmstate\"),\n mem: join(home, \"snapshots\", name, \"mem\"),\n disk: join(home, \"snapshots\", name, \"disk.ext4\"),\n }),\n } as const;\n}\n\nexport type Paths = ReturnType<typeof paths>;\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { gb, info, json, table } from \"../../output.js\";\n\n/** kvbox vm ls [--json] — --json output: Machine[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list boxes with status and IP\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const boxes = await client.listMachines();\n if (opts.json) {\n json(boxes);\n return;\n }\n if (boxes.length === 0) {\n info(\"no boxes yet; create one with: kvbox new\");\n return;\n }\n table(\n boxes.map((b) => ({\n name: b.name,\n status: b.status,\n ip: b.ip,\n cpu: `${b.vcpu} vCPU`,\n ram: gb(b.memMib * 1024 ** 2),\n disk: `${gb(b.diskBytes)} (${gb(b.diskUsedBytes)} used)`,\n source: b.source,\n created: b.createdAt.replace(\"T\", \" \").slice(0, 16),\n })),\n );\n } finally {\n await client.close();\n }\n });\n","import { Command, Option } from \"commander\";\nimport type { Machine } from \"@kvbox/shared/api\";\nimport { SIZE_NAMES } from \"@kvbox/shared/sizes\";\nimport { clientFor } from \"../../client.js\";\nimport { color, gb, info, json } from \"../../output.js\";\n\n/**\n * kvbox vm new [name] [--size s|m|l] [--from <snapshot>] [--force] [--json]\n * --json output: the Machine object (see packages/shared/src/api.ts).\n */\nexport const newCommand = new Command(\"new\")\n .description(\"boot a new box from the base image or a snapshot\")\n .argument(\"[name]\", \"box name (box1, box2, … when omitted)\")\n .addOption(new Option(\"-s, --size <size>\", \"box size (default: server config, s)\").choices(SIZE_NAMES))\n .option(\"-f, --from <snapshot>\", \"start from a snapshot instead of the base image\")\n .option(\"--force\", \"skip the capacity guard\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string | undefined, opts: { size?: string; from?: string; force?: boolean; json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.createMachine({\n ...(name !== undefined ? { name } : {}),\n ...(opts.size !== undefined ? { size: opts.size } : {}),\n ...(opts.from !== undefined ? { from: opts.from } : {}),\n ...(opts.force ? { force: true } : {}),\n });\n if (opts.json) {\n json(box);\n return;\n }\n process.stdout.write(`${box.name}\\n`);\n info(`${color.green(\"✓\")} ${describe(box)}`);\n info(` connect with: kvbox connect ${box.name} (SSH is up a couple of seconds after boot)`);\n } finally {\n await client.close();\n }\n });\n\nexport function describe(box: Machine): string {\n return `box ${color.bold(box.name)} is ${box.status} at ${box.ip}: ${box.vcpu} vCPU, ${gb(box.memMib * 1024 ** 2)} RAM, ${gb(box.diskBytes)} disk`;\n}\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, confirm, info } from \"../../output.js\";\n\n/** kvbox vm rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"destroy a box (its disk is deleted; snapshots are kept)\")\n .argument(\"<name>\", \"box name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(async (name: string, opts: { yes?: boolean }, cmd: Command) => {\n if (!(await confirm(`Destroy box ${name} and its disk?`, opts.yes ?? false))) {\n info(\"cancelled\");\n process.exitCode = 1;\n return;\n }\n const client = clientFor(cmd.optsWithGlobals());\n try {\n await client.deleteMachine(name);\n info(`${color.green(\"✓\")} box ${name} destroyed`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\nimport { describe } from \"./new.js\";\n\n/** kvbox vm start <name> [--json] — boot a stopped box from its own disk; --json output: the Machine object */\nexport const startCommand = new Command(\"start\")\n .description(\"boot a stopped box again (same name, IP and disk)\")\n .argument(\"<name>\", \"box name\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.startMachine(name);\n if (opts.json) json(box);\n else info(`${color.green(\"✓\")} ${describe(box)}`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\n\n/** kvbox vm stop <name> [--json] — clean shutdown, disk kept; --json output: the Machine object */\nexport const stopCommand = new Command(\"stop\")\n .description(\"shut a box down (its disk is kept; start it again with kvbox start)\")\n .argument(\"<name>\", \"box name\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.stopMachine(name);\n if (opts.json) json(box);\n else info(`${color.green(\"✓\")} box ${name} stopped (disk kept; kvbox start ${name} boots it again)`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { startCommand } from \"./start.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\n\nexport const serverCommand = new Command(\"server\")\n .description(\"run or manage the kvbox server\")\n .addCommand(startCommand)\n .addCommand(statusCommand)\n .addCommand(stopCommand);\n","/**\n * kvbox server start\n * Starts the local `kvbox-server` (a separate package) detached, logging to\n * ~/.kvbox/server.log, and waits for its socket. The CLI never imports server code.\n */\nimport { Command } from \"commander\";\nimport { paths } from \"@kvbox/shared/paths\";\nimport { clientFor, startLocalServer } from \"../../client.js\";\nimport { info } from \"../../output.js\";\n\nexport const startCommand = new Command(\"start\")\n .description(\"start the local kvbox-server in the background\")\n .action(async (_opts: Record<string, never>, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals(), { autoStart: false });\n try {\n const health = await client.health();\n info(`kvbox-server ${health.version} is already running (pid ${health.pid})`);\n return;\n } catch {\n // not running: start it\n } finally {\n await client.close();\n }\n const { pid, socketPath } = await startLocalServer(paths());\n info(`kvbox-server started (pid ${pid}), listening on ${socketPath}`);\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { info, json } from \"../../output.js\";\n\n/** kvbox server status [--json] — --json output: Health */\nexport const statusCommand = new Command(\"status\")\n .description(\"show whether the server is running\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const health = await client.health();\n if (opts.json) json(health);\n else info(`kvbox-server ${health.version} running, pid ${health.pid}`);\n } finally {\n await client.close();\n }\n });\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { paths } from \"@kvbox/shared/paths\";\nimport { info } from \"../../output.js\";\n\n/** kvbox server stop — SIGTERM the pid in server.pid. Boxes keep running. */\nexport const stopCommand = new Command(\"stop\")\n .description(\"stop the local server (running boxes are not affected)\")\n .action(async () => {\n const p = paths();\n let pid: number;\n try {\n pid = Number.parseInt(await readFile(p.serverPid, \"utf8\"), 10);\n } catch {\n throw new KvboxError(\"kvbox-server is not running (no pid file)\");\n }\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {\n throw new KvboxError(`kvbox-server pid ${pid} is not running; remove ${p.serverPid}`);\n }\n info(`sent SIGTERM to kvbox-server (pid ${pid})`);\n });\n","import { Command } from \"commander\";\nimport { lsCommand } from \"./ls.js\";\nimport { rmCommand } from \"./rm.js\";\nimport { saveCommand } from \"./save.js\";\n\nexport const snapshotCommand = new Command(\"snapshot\")\n .alias(\"snap\")\n .description(\"manage snapshots\")\n .addCommand(saveCommand)\n .addCommand(lsCommand)\n .addCommand(rmCommand);\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot ls [--json] — --json output: Snapshot[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list snapshots\")\n .option(\"--json\", \"print as JSON\")\n .action(() => notImplemented(\"snapshot ls\"));\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"delete a snapshot\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(() => notImplemented(\"snapshot rm\"));\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot save <box> <name> [--json] — --json output: Snapshot */\nexport const saveCommand = new Command(\"save\")\n .description(\"freeze a running box (memory + disk) into a snapshot\")\n .argument(\"<box>\", \"box name\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"--json\", \"print the snapshot as JSON\")\n .action(() => notImplemented(\"snapshot save\"));\n","/** Entry point: parse argv, map KvboxError to an exit code. */\nimport { color } from \"./output.js\";\nimport { buildProgram } from \"./program.js\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\n\ntry {\n await buildProgram().parseAsync(process.argv);\n} catch (err) {\n if (err instanceof KvboxError) {\n process.stderr.write(color.red(`error: ${err.message}`) + \"\\n\");\n process.exit(err.exitCode);\n }\n throw err;\n}\n"],"mappings":"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","names":["Command","require","Command","z","z","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","startCommand","Command","Command","Command","Command","stopCommand","Command","Command","startCommand","stopCommand","Command","Command","lsCommand","Command","Command","rmCommand","Command","Command","Command","Command","lsCommand","rmCommand","Command"]}
1
+ {"version":3,"sources":["../src/output.ts","../src/program.ts","../../shared/src/version.ts","../src/version.ts","../src/commands/vm/index.ts","../src/commands/vm/connect.ts","../../shared/src/errors.ts","../src/client.ts","../../shared/src/api.ts","../../shared/src/sizes.ts","../../shared/src/paths.ts","../src/commands/vm/ls.ts","../src/commands/vm/new.ts","../src/commands/vm/rm.ts","../src/commands/vm/start.ts","../src/commands/vm/stop.ts","../src/commands/server/index.ts","../src/commands/server/start.ts","../src/commands/server/status.ts","../src/commands/server/stop.ts","../src/commands/snapshot/index.ts","../src/commands/snapshot/ls.ts","../src/commands/snapshot/rm.ts","../src/commands/snapshot/save.ts","../src/index.ts"],"sourcesContent":["/** Printing: tables for humans, `--json` for agents, colors only on a TTY. */\nimport pc from \"picocolors\";\n\nexport const color = pc.createColors(process.stdout.isTTY === true && !process.env[\"NO_COLOR\"]);\n\nexport function json(value: unknown): void {\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\");\n}\n\nexport function table(rows: Record<string, string | number | null | undefined>[], columns?: string[]): void {\n if (rows.length === 0) return;\n const cols = columns ?? Object.keys(rows[0]!);\n const cells = rows.map((r) => cols.map((c) => String(r[c] ?? \"\")));\n const widths = cols.map((c, i) => Math.max(c.length, ...cells.map((r) => r[i]!.length)));\n const line = (parts: string[]) => parts.map((p, i) => p.padEnd(widths[i]!)).join(\" \").trimEnd();\n process.stdout.write(color.dim(line(cols.map((c) => c.toUpperCase()))) + \"\\n\");\n for (const row of cells) process.stdout.write(line(row) + \"\\n\");\n}\n\nexport function info(msg: string): void {\n process.stderr.write(msg + \"\\n\");\n}\n\nexport function warn(msg: string): void {\n process.stderr.write(color.yellow(msg) + \"\\n\");\n}\n\nexport function notImplemented(command: string): never {\n process.stderr.write(color.yellow(`kvbox ${command}: not implemented yet\\n`));\n process.exit(2);\n}\n\n/** y/N prompt on a TTY; requires `-y` otherwise (boxd's rule for destructive commands). */\nexport async function confirm(question: string, yes: boolean): Promise<boolean> {\n if (yes) return true;\n if (!process.stdin.isTTY) {\n warn(\"refusing without -y when stdin is not a terminal\");\n return false;\n }\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n try {\n const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\n/** Bytes for humans: 4 GiB -> \"4 GB\", 3.4 GiB -> \"3.4 GB\", under 1 GiB -> \"640 MB\". */\nexport function gb(bytes: number): string {\n const g = bytes / 1024 ** 3;\n if (g >= 1) return `${Number.isInteger(g) ? g : g.toFixed(1)} GB`;\n return `${Math.round(bytes / 1024 ** 2)} MB`;\n}\n","/** Builds the commander tree. Importable without side effects (tests); src/index.ts runs it. */\nimport { Command } from \"commander\";\nimport { VERSION } from \"./version.js\";\nimport { vmAliases, vmCommand } from \"./commands/vm/index.js\";\nimport { serverCommand } from \"./commands/server/index.js\";\nimport { snapshotCommand } from \"./commands/snapshot/index.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"kvbox\")\n .description(\"self-hosted Firecracker microVMs with Docker-like ergonomics\")\n .version(VERSION, \"-v, --version\")\n .option(\"--host <name>\", \"target a configured remote host (M2)\")\n .showHelpAfterError()\n .enablePositionalOptions();\n\n program.addCommand(vmCommand);\n program.addCommand(snapshotCommand);\n program.addCommand(serverCommand);\n // Top-level shortcuts: the same Command objects as under `vm`.\n for (const cmd of vmAliases) program.addCommand(cmd);\n\n return program;\n}\n","/**\n * Each binary's version comes from its own package.json: tsup injects\n * `__KVBOX_VERSION__` at build time; the dev path (tsx) reads the file.\n * Usage in a package: `versionOf(import.meta.url)` from its `src/version.ts`.\n */\nimport { createRequire } from \"node:module\";\n\nexport function versionOf(srcFileUrl: string, injected?: string): string {\n if (typeof injected === \"string\") return injected;\n try {\n const require = createRequire(srcFileUrl);\n return (require(\"../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0-dev\";\n }\n}\n","import { versionOf } from \"@kvbox/shared/version\";\n\ndeclare const __KVBOX_VERSION__: string | undefined;\n\nexport const VERSION: string = versionOf(import.meta.url, typeof __KVBOX_VERSION__ === \"string\" ? __KVBOX_VERSION__ : undefined);\n","import { Command } from \"commander\";\nimport { connectCommand } from \"./connect.js\";\nimport { lsCommand } from \"./ls.js\";\nimport { newCommand } from \"./new.js\";\nimport { rmCommand } from \"./rm.js\";\nimport { startCommand } from \"./start.js\";\nimport { stopCommand } from \"./stop.js\";\n\nexport const vmCommand = new Command(\"vm\")\n .enablePositionalOptions()\n .description(\"manage boxes (each one is a Firecracker microVM)\")\n .addCommand(newCommand)\n .addCommand(lsCommand)\n .addCommand(connectCommand)\n .addCommand(stopCommand)\n .addCommand(startCommand)\n .addCommand(rmCommand);\n\n/** The same Command objects, added again at the top level so they cannot drift. */\nexport const vmAliases = [newCommand, lsCommand, connectCommand, stopCommand, startCommand, rmCommand];\n","import { spawnSync } from \"node:child_process\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs } from \"../../client.js\";\n\n/** kvbox vm connect <name> [-- cmd...] — ssh kvbox@<ip> with the kvbox key; a shell, or run a command */\nexport const connectCommand = new Command(\"connect\")\n .description(\"open a shell in a box over SSH (or run a command: kvbox connect <name> -- <cmd>)\")\n .argument(\"<name>\", \"box name\")\n .argument(\"[cmd...]\", \"command to run instead of a shell\")\n .passThroughOptions()\n .action(async (name: string, cmdArgs: string[], _opts: unknown, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n let ip: string;\n try {\n const box = (await client.listMachines()).find((b) => b.name === name);\n if (!box) throw new KvboxError(`box ${name}: not found (kvbox ls)`);\n if (box.status !== \"running\") throw new KvboxError(`box ${name} is ${box.status}`);\n ip = box.ip;\n } finally {\n await client.close();\n }\n const res = spawnSync(\"ssh\", [...sshArgs(ip), ...cmdArgs], { stdio: \"inherit\" });\n if (res.error) throw new KvboxError(`could not run ssh: ${res.error.message}`);\n process.exit(res.status ?? 1);\n });\n","/** Errors with an exit code; the entry point prints `message` and exits with `exitCode`. */\nexport class KvboxError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = 1,\n ) {\n super(message);\n this.name = \"KvboxError\";\n }\n}\n\nexport class NotImplementedError extends KvboxError {\n constructor(what: string) {\n super(`${what}: not implemented yet`, 2);\n this.name = \"NotImplementedError\";\n }\n}\n\n/** The named box/snapshot/host does not exist: HTTP 404, exit 1. */\nexport class NotFoundError extends KvboxError {\n constructor(what: string) {\n super(`${what}: not found`, 1);\n this.name = \"NotFoundError\";\n }\n}\n","/**\n * ServerClient: one method per route of the kvbox API, over undici.\n * Target resolution: `--host` -> configured hosts (M2) -> local Unix socket.\n * Auto-starting the local server from every command when nothing listens is #17;\n * `startLocalServer` below is the piece it will reuse.\n */\nimport { spawn } from \"node:child_process\";\nimport { openSync } from \"node:fs\";\nimport { mkdir, stat } from \"node:fs/promises\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\nimport { Agent, request, type Dispatcher } from \"undici\";\nimport { z } from \"zod\";\nimport {\n ApiErrorSchema,\n CapacitySchema,\n HealthSchema,\n MachineSchema,\n SnapshotSchema,\n type CreateMachineRequest,\n type CreateSnapshotRequest,\n} from \"@kvbox/shared/api\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { paths, type Paths } from \"@kvbox/shared/paths\";\n\nexport type Target = { kind: \"local\"; socketPath: string } | { kind: \"remote\"; name: string; url: string };\n\nexport function resolveTarget(hostFlag?: string): Target {\n if (hostFlag) {\n throw new KvboxError(`--host ${hostFlag}: remote hosts arrive in M2`);\n }\n return { kind: \"local\", socketPath: paths().serverSock };\n}\n\nexport interface ClientOptions {\n /** Spawn `kvbox-server` when the local socket does not answer (default true; the start probe turns it off). */\n autoStart?: boolean;\n}\n\nexport class ServerClient {\n private readonly dispatcher: Dispatcher;\n private readonly base: string;\n private readonly autoStart: boolean;\n private startedOnce = false;\n\n constructor(\n readonly target: Target,\n opts: ClientOptions = {},\n ) {\n this.autoStart = opts.autoStart ?? true;\n if (target.kind === \"local\") {\n this.dispatcher = new Agent({ connect: { socketPath: target.socketPath } });\n this.base = \"http://kvbox\";\n } else {\n this.dispatcher = new Agent();\n this.base = target.url;\n }\n }\n\n private async call<T>(\n method: \"GET\" | \"POST\" | \"DELETE\",\n path: string,\n schema: z.ZodType<T>,\n body?: unknown,\n ): Promise<T> {\n let res;\n try {\n res = await request(this.base + path, {\n dispatcher: this.dispatcher,\n method,\n headers: body === undefined ? {} : { \"content-type\": \"application/json\" },\n body: body === undefined ? null : JSON.stringify(body),\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code ?? (err as Error).cause;\n if (this.target.kind === \"local\") {\n // Nothing listens locally: start the daemon once and retry (architecture: \"auto-start\").\n if (this.autoStart && !this.startedOnce) {\n this.startedOnce = true;\n await startLocalServer(paths(), 5000);\n return this.call(method, path, schema, body);\n }\n throw new KvboxError(`kvbox-server is not running (${String(code)}); start it with: kvbox server start`);\n }\n throw new KvboxError(`cannot reach ${this.target.name}: ${String(code)}`);\n }\n const text = await res.body.text();\n if (res.statusCode >= 300) {\n const parsed = ApiErrorSchema.safeParse(text ? JSON.parse(text) : {});\n const msg = parsed.success ? parsed.data.error : `${res.statusCode} ${text}`;\n throw new KvboxError(msg, res.statusCode === 501 ? 2 : 1);\n }\n return schema.parse(text ? JSON.parse(text) : undefined);\n }\n\n health() {\n return this.call(\"GET\", \"/health\", HealthSchema);\n }\n\n capacity() {\n return this.call(\"GET\", \"/capacity\", CapacitySchema);\n }\n\n listMachines() {\n return this.call(\"GET\", \"/machines\", z.array(MachineSchema));\n }\n\n createMachine(req: CreateMachineRequest) {\n return this.call(\"POST\", \"/machines\", MachineSchema, req);\n }\n\n stopMachine(name: string) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/stop`, MachineSchema);\n }\n\n startMachine(name: string) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/start`, MachineSchema);\n }\n\n deleteMachine(name: string) {\n return this.call(\"DELETE\", `/machines/${encodeURIComponent(name)}`, z.undefined());\n }\n\n listSnapshots() {\n return this.call(\"GET\", \"/snapshots\", z.array(SnapshotSchema));\n }\n\n createSnapshot(req: CreateSnapshotRequest) {\n return this.call(\"POST\", \"/snapshots\", SnapshotSchema, req);\n }\n\n deleteSnapshot(name: string) {\n return this.call(\"DELETE\", `/snapshots/${encodeURIComponent(name)}`, z.undefined());\n }\n\n async close() {\n await this.dispatcher.close();\n }\n}\n\n/** Build a client from the global `--host` option of the root command. */\nexport function clientFor(opts: { host?: string }, client: ClientOptions = {}): ServerClient {\n return new ServerClient(resolveTarget(opts.host), client);\n}\n\n/**\n * `ssh` argv for a box. Host keys are per box and IPs get reused, so no known_hosts;\n * SetEnv pins the locale because the image only ships C.UTF-8 (#24).\n */\nexport function sshArgs(ip: string, keyPath: string = paths().sshKey): string[] {\n return [\n \"-i\", keyPath,\n \"-o\", \"StrictHostKeyChecking=no\",\n \"-o\", \"UserKnownHostsFile=/dev/null\",\n \"-o\", \"LogLevel=ERROR\",\n \"-o\", \"SetEnv=LC_ALL=C.UTF-8\",\n `kvbox@${ip}`,\n ];\n}\n\nexport const NOT_A_HOST_HINT =\n \"kvbox-server is not installed, so this machine is not a kvbox host. \" +\n \"Set it up with install-server.sh, or point the CLI at a remote host (M2: kvbox host add).\";\n\n/**\n * Spawn `kvbox-server start` from PATH, detached, stdio to ~/.kvbox/server.log,\n * and resolve once its socket accepts a /health call (or reject after `timeoutMs`).\n */\nexport async function startLocalServer(p: Paths = paths(), timeoutMs = 5000): Promise<{ pid: number; socketPath: string }> {\n await mkdir(p.home, { recursive: true });\n const log = openSync(p.serverLog, \"a\");\n const child = spawn(\"kvbox-server\", [\"start\"], { detached: true, stdio: [\"ignore\", log, log] });\n\n const failed = new Promise<never>((_, reject) => {\n child.once(\"error\", (err: NodeJS.ErrnoException) => {\n reject(new KvboxError(err.code === \"ENOENT\" ? NOT_A_HOST_HINT : `could not start kvbox-server: ${err.message}`));\n });\n child.once(\"exit\", (code) => {\n reject(new KvboxError(`kvbox-server exited with code ${String(code)} before listening; see ${p.serverLog}`));\n });\n });\n\n const ready = (async () => {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await stat(p.serverSock).then(() => true, () => false)) {\n const probe = new ServerClient({ kind: \"local\", socketPath: p.serverSock }, { autoStart: false });\n try {\n await probe.health();\n return;\n } catch {\n // socket exists but not serving yet\n } finally {\n await probe.close();\n }\n }\n await sleep(100);\n }\n throw new KvboxError(`kvbox-server did not start within ${timeoutMs / 1000}s; see ${p.serverLog}`);\n })();\n\n await Promise.race([ready, failed]);\n child.removeAllListeners(\"exit\");\n child.unref();\n return { pid: child.pid ?? -1, socketPath: p.serverSock };\n}\n","/**\n * Wire shapes of the kvbox HTTP API, shared by the client (src/cli) and the\n * server (src/server). Validated with zod on both sides because the client\n * may be talking to an older or newer server.\n */\nimport { z } from \"zod\";\nimport { SIZE_NAMES } from \"./sizes.js\";\n\nexport const SizeSchema = z.enum(SIZE_NAMES as [string, ...string[]]);\n\nexport const MachineSchema = z.object({\n name: z.string(),\n ip: z.string(),\n mac: z.string(),\n pid: z.number().int().nullable(),\n vcpu: z.number().int(),\n memMib: z.number().int(),\n diskBytes: z.number().int(), // the box's own writable disk, as the guest sees it\n diskUsedBytes: z.number().int(), // what that sparse file really occupies on the host\n base: z.string().nullable(), // base image version the box runs on (null: pre-overlay box with its own copy)\n createdAt: z.string(),\n source: z.string(), // \"base\" or \"snapshot:<name>\"\n status: z.enum([\"running\", \"stopped\"]),\n});\nexport type Machine = z.infer<typeof MachineSchema>;\n\nexport const CreateMachineRequest = z.object({\n name: z.string().optional(),\n size: SizeSchema.optional(),\n from: z.string().optional(),\n force: z.boolean().optional(),\n});\nexport type CreateMachineRequest = z.infer<typeof CreateMachineRequest>;\n\nexport const SnapshotSchema = z.object({\n name: z.string(),\n source: z.string(),\n vcpu: z.number().int(),\n memMib: z.number().int(),\n createdAt: z.string(),\n});\nexport type Snapshot = z.infer<typeof SnapshotSchema>;\n\nexport const CreateSnapshotRequest = z.object({\n box: z.string(),\n name: z.string(),\n});\nexport type CreateSnapshotRequest = z.infer<typeof CreateSnapshotRequest>;\n\nexport const CapacitySchema = z.object({\n hostMemMib: z.number().int(),\n hostCores: z.number().int(),\n reservedMemMib: z.number().int(),\n reservedVcpu: z.number().int(),\n running: z.number().int(),\n});\nexport type Capacity = z.infer<typeof CapacitySchema>;\n\nexport const HealthSchema = z.object({\n ok: z.literal(true),\n version: z.string(),\n pid: z.number().int(),\n});\nexport type Health = z.infer<typeof HealthSchema>;\n\nexport const ApiErrorSchema = z.object({\n error: z.string(),\n});\n","/**\n * Fixed box sizes. Firecracker backs guest memory lazily and the disk is a sparse overlay on the\n * shared base image, so a box only costs what the guest actually touches.\n */\nexport const SIZES = {\n s: { vcpu: 2, memMib: 4096, diskGib: 8 },\n m: { vcpu: 4, memMib: 8192, diskGib: 16 },\n l: { vcpu: 8, memMib: 16384, diskGib: 32 },\n} as const;\n\nexport type SizeName = keyof typeof SIZES;\nexport const SIZE_NAMES = Object.keys(SIZES) as SizeName[];\nexport const DEFAULT_SIZE: SizeName = \"s\";\n\nexport function isSizeName(value: string): value is SizeName {\n return value in SIZES;\n}\n","/**\n * Host state layout. The filesystem is the database and `~/.kvbox` is its root.\n * This module is dependency-free so both the CLI (socket path, hosts.json)\n * and core (everything else) can use it without crossing the layer boundary.\n *\n * `KVBOX_HOME` overrides the root, mainly for tests.\n */\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport function kvboxHome(): string {\n return process.env[\"KVBOX_HOME\"] ?? join(homedir(), \".kvbox\");\n}\n\nexport function paths(home: string = kvboxHome()) {\n return {\n home,\n config: join(home, \"config.json\"),\n serverSock: join(home, \"server.sock\"),\n serverPid: join(home, \"server.pid\"),\n serverLog: join(home, \"server.log\"),\n hosts: join(home, \"hosts.json\"),\n ssh: join(home, \"ssh\"),\n sshKey: join(home, \"ssh\", \"id_ed25519\"),\n bin: join(home, \"bin\"),\n firecracker: join(home, \"bin\", \"firecracker\"),\n assets: join(home, \"assets\"),\n kernel: join(home, \"assets\", \"vmlinux\"),\n /** Symlink to the current base image, assets/rootfs-<version>.ext4; boxes keep using the version they were made from. */\n rootfs: join(home, \"assets\", \"rootfs.ext4\"),\n baseImage: (version: string) => join(home, \"assets\", `rootfs-${version}.ext4`),\n machines: join(home, \"machines\"),\n snapshots: join(home, \"snapshots\"),\n machine: (name: string) => ({\n dir: join(home, \"machines\", name),\n meta: join(home, \"machines\", name, \"meta.json\"),\n /** The box's writable layer, stacked on the read-only base image inside the guest. */\n overlay: join(home, \"machines\", name, \"overlay.ext4\"),\n /** Boxes made before overlays: a full copy of the base image. Kept bootable, never created anymore. */\n disk: join(home, \"machines\", name, \"disk.ext4\"),\n sock: join(home, \"machines\", name, \"fc.sock\"),\n log: join(home, \"machines\", name, \"fc.log\"),\n }),\n snapshot: (name: string) => ({\n dir: join(home, \"snapshots\", name),\n meta: join(home, \"snapshots\", name, \"meta.json\"),\n vmstate: join(home, \"snapshots\", name, \"vmstate\"),\n mem: join(home, \"snapshots\", name, \"mem\"),\n disk: join(home, \"snapshots\", name, \"disk.ext4\"),\n }),\n } as const;\n}\n\nexport type Paths = ReturnType<typeof paths>;\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { gb, info, json, table } from \"../../output.js\";\n\n/** kvbox vm ls [--json] — --json output: Machine[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list boxes with status and IP\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const boxes = await client.listMachines();\n if (opts.json) {\n json(boxes);\n return;\n }\n if (boxes.length === 0) {\n info(\"no boxes yet; create one with: kvbox new\");\n return;\n }\n table(\n boxes.map((b) => ({\n name: b.name,\n status: b.status,\n ip: b.ip,\n cpu: `${b.vcpu} vCPU`,\n ram: gb(b.memMib * 1024 ** 2),\n disk: `${gb(b.diskBytes)} (${gb(b.diskUsedBytes)} used)`,\n source: b.base !== null && b.source === \"base\" ? `base ${b.base}` : b.source,\n created: b.createdAt.replace(\"T\", \" \").slice(0, 16),\n })),\n );\n } finally {\n await client.close();\n }\n });\n","import { Command, Option } from \"commander\";\nimport type { Machine } from \"@kvbox/shared/api\";\nimport { SIZE_NAMES } from \"@kvbox/shared/sizes\";\nimport { clientFor } from \"../../client.js\";\nimport { color, gb, info, json } from \"../../output.js\";\n\n/**\n * kvbox vm new [name] [--size s|m|l] [--from <snapshot>] [--force] [--json]\n * --json output: the Machine object (see packages/shared/src/api.ts).\n */\nexport const newCommand = new Command(\"new\")\n .description(\"boot a new box from the base image or a snapshot\")\n .argument(\"[name]\", \"box name (box1, box2, … when omitted)\")\n .addOption(new Option(\"-s, --size <size>\", \"box size (default: server config, s)\").choices(SIZE_NAMES))\n .option(\"-f, --from <snapshot>\", \"start from a snapshot instead of the base image\")\n .option(\"--force\", \"skip the capacity guard\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string | undefined, opts: { size?: string; from?: string; force?: boolean; json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.createMachine({\n ...(name !== undefined ? { name } : {}),\n ...(opts.size !== undefined ? { size: opts.size } : {}),\n ...(opts.from !== undefined ? { from: opts.from } : {}),\n ...(opts.force ? { force: true } : {}),\n });\n if (opts.json) {\n json(box);\n return;\n }\n process.stdout.write(`${box.name}\\n`);\n info(`${color.green(\"✓\")} ${describe(box)}`);\n info(` connect with: kvbox connect ${box.name} (SSH is up a couple of seconds after boot)`);\n } finally {\n await client.close();\n }\n });\n\nexport function describe(box: Machine): string {\n return `box ${color.bold(box.name)} is ${box.status} at ${box.ip}: ${box.vcpu} vCPU, ${gb(box.memMib * 1024 ** 2)} RAM, ${gb(box.diskBytes)} disk`;\n}\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, confirm, info } from \"../../output.js\";\n\n/** kvbox vm rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"destroy a box (its disk is deleted; snapshots are kept)\")\n .argument(\"<name>\", \"box name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(async (name: string, opts: { yes?: boolean }, cmd: Command) => {\n if (!(await confirm(`Destroy box ${name} and its disk?`, opts.yes ?? false))) {\n info(\"cancelled\");\n process.exitCode = 1;\n return;\n }\n const client = clientFor(cmd.optsWithGlobals());\n try {\n await client.deleteMachine(name);\n info(`${color.green(\"✓\")} box ${name} destroyed`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\nimport { describe } from \"./new.js\";\n\n/** kvbox vm start <name> [--json] — boot a stopped box from its own disk; --json output: the Machine object */\nexport const startCommand = new Command(\"start\")\n .description(\"boot a stopped box again (same name, IP and disk)\")\n .argument(\"<name>\", \"box name\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.startMachine(name);\n if (opts.json) json(box);\n else info(`${color.green(\"✓\")} ${describe(box)}`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\n\n/** kvbox vm stop <name> [--json] — clean shutdown, disk kept; --json output: the Machine object */\nexport const stopCommand = new Command(\"stop\")\n .description(\"shut a box down (its disk is kept; start it again with kvbox start)\")\n .argument(\"<name>\", \"box name\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const box = await client.stopMachine(name);\n if (opts.json) json(box);\n else info(`${color.green(\"✓\")} box ${name} stopped (disk kept; kvbox start ${name} boots it again)`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { startCommand } from \"./start.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\n\nexport const serverCommand = new Command(\"server\")\n .description(\"run or manage the kvbox server\")\n .addCommand(startCommand)\n .addCommand(statusCommand)\n .addCommand(stopCommand);\n","/**\n * kvbox server start\n * Starts the local `kvbox-server` (a separate package) detached, logging to\n * ~/.kvbox/server.log, and waits for its socket. The CLI never imports server code.\n */\nimport { Command } from \"commander\";\nimport { paths } from \"@kvbox/shared/paths\";\nimport { clientFor, startLocalServer } from \"../../client.js\";\nimport { info } from \"../../output.js\";\n\nexport const startCommand = new Command(\"start\")\n .description(\"start the local kvbox-server in the background\")\n .action(async (_opts: Record<string, never>, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals(), { autoStart: false });\n try {\n const health = await client.health();\n info(`kvbox-server ${health.version} is already running (pid ${health.pid})`);\n return;\n } catch {\n // not running: start it\n } finally {\n await client.close();\n }\n const { pid, socketPath } = await startLocalServer(paths());\n info(`kvbox-server started (pid ${pid}), listening on ${socketPath}`);\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { info, json } from \"../../output.js\";\n\n/** kvbox server status [--json] — --json output: Health */\nexport const statusCommand = new Command(\"status\")\n .description(\"show whether the server is running\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const health = await client.health();\n if (opts.json) json(health);\n else info(`kvbox-server ${health.version} running, pid ${health.pid}`);\n } finally {\n await client.close();\n }\n });\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { paths } from \"@kvbox/shared/paths\";\nimport { info } from \"../../output.js\";\n\n/** kvbox server stop — SIGTERM the pid in server.pid. Boxes keep running. */\nexport const stopCommand = new Command(\"stop\")\n .description(\"stop the local server (running boxes are not affected)\")\n .action(async () => {\n const p = paths();\n let pid: number;\n try {\n pid = Number.parseInt(await readFile(p.serverPid, \"utf8\"), 10);\n } catch {\n throw new KvboxError(\"kvbox-server is not running (no pid file)\");\n }\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {\n throw new KvboxError(`kvbox-server pid ${pid} is not running; remove ${p.serverPid}`);\n }\n info(`sent SIGTERM to kvbox-server (pid ${pid})`);\n });\n","import { Command } from \"commander\";\nimport { lsCommand } from \"./ls.js\";\nimport { rmCommand } from \"./rm.js\";\nimport { saveCommand } from \"./save.js\";\n\nexport const snapshotCommand = new Command(\"snapshot\")\n .alias(\"snap\")\n .description(\"manage snapshots\")\n .addCommand(saveCommand)\n .addCommand(lsCommand)\n .addCommand(rmCommand);\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot ls [--json] — --json output: Snapshot[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list snapshots\")\n .option(\"--json\", \"print as JSON\")\n .action(() => notImplemented(\"snapshot ls\"));\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"delete a snapshot\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(() => notImplemented(\"snapshot rm\"));\n","import { Command } from \"commander\";\nimport { notImplemented } from \"../../output.js\";\n\n/** kvbox snapshot save <box> <name> [--json] — --json output: Snapshot */\nexport const saveCommand = new Command(\"save\")\n .description(\"freeze a running box (memory + disk) into a snapshot\")\n .argument(\"<box>\", \"box name\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"--json\", \"print the snapshot as JSON\")\n .action(() => notImplemented(\"snapshot save\"));\n","/** Entry point: parse argv, map KvboxError to an exit code. */\nimport { color } from \"./output.js\";\nimport { buildProgram } from \"./program.js\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\n\ntry {\n await buildProgram().parseAsync(process.argv);\n} catch (err) {\n if (err instanceof KvboxError) {\n process.stderr.write(color.red(`error: ${err.message}`) + \"\\n\");\n process.exit(err.exitCode);\n }\n throw err;\n}\n"],"mappings":"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","names":["Command","require","Command","z","z","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","startCommand","Command","Command","Command","Command","stopCommand","Command","Command","startCommand","stopCommand","Command","Command","lsCommand","Command","Command","rmCommand","Command","Command","Command","Command","lsCommand","rmCommand","Command"]}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@ghalex/kvbox",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "kvbox CLI: manage Firecracker microVM hosts with Docker-like commands. Thin client; the host runs @ghalex/kvbox-server.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "bin": {
8
- "kvbox": "./dist/kvbox.js"
8
+ "kvbox": "dist/kvbox.js"
9
9
  },
10
10
  "files": [
11
11
  "dist"
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/ghalex/kvbox",
18
+ "url": "git+https://github.com/ghalex/kvbox.git",
19
19
  "directory": "packages/cli"
20
20
  },
21
21
  "homepage": "https://kvbox.sh",