@ghalex/kvbox 0.0.11 → 0.0.12

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
@@ -71,7 +71,7 @@ function age(iso, now = Date.now()) {
71
71
  }
72
72
 
73
73
  // src/program.ts
74
- import { Command as Command17 } from "commander";
74
+ import { Command as Command19 } from "commander";
75
75
 
76
76
  // ../shared/src/version.ts
77
77
  import { createRequire } from "module";
@@ -86,10 +86,10 @@ function versionOf(srcFileUrl, injected) {
86
86
  }
87
87
 
88
88
  // src/version.ts
89
- var VERSION = versionOf(import.meta.url, true ? "0.0.11" : void 0);
89
+ var VERSION = versionOf(import.meta.url, true ? "0.0.12" : void 0);
90
90
 
91
91
  // src/commands/vm/index.ts
92
- import { Command as Command8 } from "commander";
92
+ import { Command as Command10 } from "commander";
93
93
 
94
94
  // src/commands/vm/connect.ts
95
95
  import { spawnSync } from "child_process";
@@ -123,6 +123,14 @@ var SIZES = {
123
123
  l: { vcpu: 8, memMib: 16384, diskGib: 32 }
124
124
  };
125
125
  var SIZE_NAMES = Object.keys(SIZES);
126
+ function parseMib(text) {
127
+ const m = /^\s*(\d+(?:\.\d+)?)\s*([gm]i?b?)?\s*$/i.exec(text);
128
+ if (!m) return void 0;
129
+ const n = Number(m[1]);
130
+ const unit = (m[2] ?? "g").toLowerCase();
131
+ const mib = unit.startsWith("m") ? n : n * 1024;
132
+ return Number.isInteger(mib) && mib > 0 ? mib : void 0;
133
+ }
126
134
 
127
135
  // ../shared/src/api.ts
128
136
  var SizeSchema = z.enum(SIZE_NAMES);
@@ -150,6 +158,12 @@ var CreateMachineRequest = z.object({
150
158
  from: z.string().optional(),
151
159
  force: z.boolean().optional()
152
160
  });
161
+ var RescaleMachineRequest = z.object({
162
+ size: SizeSchema.optional(),
163
+ vcpu: z.number().int().min(1).max(64).optional(),
164
+ memMib: z.number().int().min(256).optional(),
165
+ diskGib: z.number().int().min(1).optional()
166
+ });
153
167
  var SnapshotSchema = z.object({
154
168
  name: z.string(),
155
169
  source: z.string(),
@@ -308,6 +322,12 @@ var ServerClient = class {
308
322
  startMachine(name) {
309
323
  return this.call("POST", `/machines/${encodeURIComponent(name)}/start`, MachineSchema);
310
324
  }
325
+ updateMachine(name) {
326
+ return this.call("POST", `/machines/${encodeURIComponent(name)}/update`, MachineSchema);
327
+ }
328
+ rescaleMachine(name, req) {
329
+ return this.call("POST", `/machines/${encodeURIComponent(name)}/rescale`, MachineSchema, req);
330
+ }
311
331
  deleteMachine(name) {
312
332
  return this.call("DELETE", `/machines/${encodeURIComponent(name)}`, z2.undefined());
313
333
  }
@@ -553,9 +573,55 @@ function describe(box) {
553
573
  return `box ${color.bold(box.name)} is ${box.status} at ${box.ip}${from}: ${box.vcpu} vCPU, ${gb(box.memMib * 1024 ** 2)} RAM, ${gb(box.diskBytes)} disk`;
554
574
  }
555
575
 
576
+ // src/commands/vm/rescale.ts
577
+ import { Command as Command5, Option as Option2 } from "commander";
578
+ var rescaleCommand = new Command5("rescale").description("change a box's vCPUs, memory or disk (e.g. --vcpu 4 --mem 16GB); a running box restarts").argument("<name>", "box name").addOption(new Option2("-s, --size <size>", "a preset to start from").choices(SIZE_NAMES)).option("--vcpu <n>", "number of vCPUs").option("--mem <size>", "memory, e.g. 16GB or 4096MB").option("--disk <size>", "disk size, e.g. 32GB (grow only)").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
579
+ const req = {
580
+ ...opts.size !== void 0 ? { size: opts.size } : {},
581
+ ...opts.vcpu !== void 0 ? { vcpu: parseCount(opts.vcpu) } : {},
582
+ ...opts.mem !== void 0 ? { memMib: parseSize("--mem", opts.mem) } : {},
583
+ ...opts.disk !== void 0 ? { diskGib: parseGib("--disk", opts.disk) } : {}
584
+ };
585
+ if (Object.keys(req).length === 0) throw new KvboxError("nothing to change: give --size, --vcpu, --mem or --disk");
586
+ const client = clientFor(cmd.optsWithGlobals());
587
+ try {
588
+ const before = (await client.listMachines()).find((b) => b.name === name);
589
+ if (!before) throw new KvboxError(`box ${name}: not found (kvbox ls)`);
590
+ const box = await client.rescaleMachine(name, req);
591
+ if (opts.json) {
592
+ json(box);
593
+ return;
594
+ }
595
+ const same = box.vcpu === before.vcpu && box.memMib === before.memMib && box.diskBytes === before.diskBytes;
596
+ if (same) {
597
+ info(`box ${name} already has that shape; nothing changed`);
598
+ return;
599
+ }
600
+ info(`${color.green("\u2713")} ${describe(box)}`);
601
+ if (before.status === "running") info(" it was restarted: processes that were running are gone, files are intact");
602
+ } finally {
603
+ await client.close();
604
+ }
605
+ });
606
+ function parseCount(text) {
607
+ const n = Number(text);
608
+ if (!Number.isInteger(n) || n < 1) throw new KvboxError(`--vcpu ${text}: give a whole number of vCPUs`);
609
+ return n;
610
+ }
611
+ function parseSize(flag, text) {
612
+ const mib = parseMib(text);
613
+ if (mib === void 0) throw new KvboxError(`${flag} ${text}: give a size like 16GB or 4096MB`);
614
+ return mib;
615
+ }
616
+ function parseGib(flag, text) {
617
+ const mib = parseSize(flag, text);
618
+ if (mib % 1024 !== 0) throw new KvboxError(`${flag} ${text}: disk sizes are whole GB`);
619
+ return mib / 1024;
620
+ }
621
+
556
622
  // src/commands/vm/rm.ts
557
- import { Command as Command5 } from "commander";
558
- var rmCommand = new Command5("rm").description("destroy a box (its disk is deleted; snapshots are kept)").argument("<name>", "box name").option("-y, --yes", "do not ask for confirmation").action(async (name, opts, cmd) => {
623
+ import { Command as Command6 } from "commander";
624
+ var rmCommand = new Command6("rm").description("destroy a box (its disk is deleted; snapshots are kept)").argument("<name>", "box name").option("-y, --yes", "do not ask for confirmation").action(async (name, opts, cmd) => {
559
625
  if (!await confirm(`Destroy box ${name} and its disk?`, opts.yes ?? false)) {
560
626
  info("cancelled");
561
627
  process.exitCode = 1;
@@ -571,8 +637,8 @@ var rmCommand = new Command5("rm").description("destroy a box (its disk is delet
571
637
  });
572
638
 
573
639
  // src/commands/vm/start.ts
574
- import { Command as Command6 } from "commander";
575
- var startCommand = new Command6("start").description("boot a stopped box again (same name, IP and disk)").argument("<name>", "box name").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
640
+ import { Command as Command7 } from "commander";
641
+ var startCommand = new Command7("start").description("boot a stopped box again (same name, IP and disk)").argument("<name>", "box name").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
576
642
  const client = clientFor(cmd.optsWithGlobals());
577
643
  try {
578
644
  const box = await client.startMachine(name);
@@ -584,8 +650,8 @@ var startCommand = new Command6("start").description("boot a stopped box again (
584
650
  });
585
651
 
586
652
  // src/commands/vm/stop.ts
587
- import { Command as Command7 } from "commander";
588
- var stopCommand = new Command7("stop").description("shut a box down (its disk is kept; start it again with kvbox start)").argument("<name>", "box name").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
653
+ import { Command as Command8 } from "commander";
654
+ var stopCommand = new Command8("stop").description("shut a box down (its disk is kept; start it again with kvbox start)").argument("<name>", "box name").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
589
655
  const client = clientFor(cmd.optsWithGlobals());
590
656
  try {
591
657
  const box = await client.stopMachine(name);
@@ -596,16 +662,39 @@ var stopCommand = new Command7("stop").description("shut a box down (its disk is
596
662
  }
597
663
  });
598
664
 
665
+ // src/commands/vm/update.ts
666
+ import { Command as Command9 } from "commander";
667
+ var updateCommand = new Command9("update").description("move a box onto the current base image (its files stay; a running box restarts)").argument("<name>", "box name").option("--json", "print the box as JSON").action(async (name, opts, cmd) => {
668
+ const client = clientFor(cmd.optsWithGlobals());
669
+ try {
670
+ const before = (await client.listMachines()).find((b) => b.name === name);
671
+ if (!before) throw new KvboxError(`box ${name}: not found (kvbox ls)`);
672
+ const box = await client.updateMachine(name);
673
+ if (opts.json) {
674
+ json(box);
675
+ return;
676
+ }
677
+ if (box.base === before.base) {
678
+ info(`box ${name} is already on base image ${box.base}`);
679
+ } else {
680
+ const restarted = before.status === "running" ? " (restarted: processes that were running are gone, files are intact)" : "";
681
+ info(`${color.green("\u2713")} box ${color.bold(name)} now runs on base image ${box.base} (was ${before.base})${restarted}`);
682
+ }
683
+ } finally {
684
+ await client.close();
685
+ }
686
+ });
687
+
599
688
  // src/commands/vm/index.ts
600
- var vmCommand = new Command8("vm").enablePositionalOptions().description("manage boxes (each one is a Firecracker microVM)").addCommand(newCommand).addCommand(lsCommand).addCommand(connectCommand).addCommand(execCommand).addCommand(stopCommand).addCommand(startCommand).addCommand(rmCommand);
601
- var vmAliases = [newCommand, lsCommand, connectCommand, execCommand, stopCommand, startCommand, rmCommand];
689
+ var vmCommand = new Command10("vm").enablePositionalOptions().description("manage boxes (each one is a Firecracker microVM)").addCommand(newCommand).addCommand(lsCommand).addCommand(connectCommand).addCommand(execCommand).addCommand(stopCommand).addCommand(startCommand).addCommand(updateCommand).addCommand(rescaleCommand).addCommand(rmCommand);
690
+ var vmAliases = [newCommand, lsCommand, connectCommand, execCommand, stopCommand, startCommand, updateCommand, rescaleCommand, rmCommand];
602
691
 
603
692
  // src/commands/server/index.ts
604
- import { Command as Command12 } from "commander";
693
+ import { Command as Command14 } from "commander";
605
694
 
606
695
  // src/commands/server/start.ts
607
- import { Command as Command9 } from "commander";
608
- var startCommand2 = new Command9("start").description("start the local kvbox-server in the background").action(async (_opts, cmd) => {
696
+ import { Command as Command11 } from "commander";
697
+ var startCommand2 = new Command11("start").description("start the local kvbox-server in the background").action(async (_opts, cmd) => {
609
698
  const client = clientFor(cmd.optsWithGlobals(), { autoStart: false });
610
699
  try {
611
700
  const health = await client.health();
@@ -620,8 +709,8 @@ var startCommand2 = new Command9("start").description("start the local kvbox-ser
620
709
  });
621
710
 
622
711
  // src/commands/server/status.ts
623
- import { Command as Command10 } from "commander";
624
- var statusCommand = new Command10("status").description("show whether the server is running").option("--json", "print as JSON").action(async (opts, cmd) => {
712
+ import { Command as Command12 } from "commander";
713
+ var statusCommand = new Command12("status").description("show whether the server is running").option("--json", "print as JSON").action(async (opts, cmd) => {
625
714
  const client = clientFor(cmd.optsWithGlobals());
626
715
  try {
627
716
  const health = await client.health();
@@ -634,8 +723,8 @@ var statusCommand = new Command10("status").description("show whether the server
634
723
 
635
724
  // src/commands/server/stop.ts
636
725
  import { readFile } from "fs/promises";
637
- import { Command as Command11 } from "commander";
638
- var stopCommand2 = new Command11("stop").description("stop the local server (running boxes are not affected)").action(async () => {
726
+ import { Command as Command13 } from "commander";
727
+ var stopCommand2 = new Command13("stop").description("stop the local server (running boxes are not affected)").action(async () => {
639
728
  const p = paths();
640
729
  let pid;
641
730
  try {
@@ -652,14 +741,14 @@ var stopCommand2 = new Command11("stop").description("stop the local server (run
652
741
  });
653
742
 
654
743
  // src/commands/server/index.ts
655
- var serverCommand = new Command12("server").description("run or manage the kvbox server").addCommand(startCommand2).addCommand(statusCommand).addCommand(stopCommand2);
744
+ var serverCommand = new Command14("server").description("run or manage the kvbox server").addCommand(startCommand2).addCommand(statusCommand).addCommand(stopCommand2);
656
745
 
657
746
  // src/commands/snapshots/index.ts
658
- import { Command as Command16 } from "commander";
747
+ import { Command as Command18 } from "commander";
659
748
 
660
749
  // src/commands/snapshots/ls.ts
661
- import { Command as Command13 } from "commander";
662
- var lsCommand2 = new Command13("ls").description("list snapshots").option("--json", "print as JSON").action(async (opts, cmd) => {
750
+ import { Command as Command15 } from "commander";
751
+ var lsCommand2 = new Command15("ls").description("list snapshots").option("--json", "print as JSON").action(async (opts, cmd) => {
663
752
  const client = clientFor(cmd.optsWithGlobals());
664
753
  try {
665
754
  const snaps = await client.listSnapshots();
@@ -686,8 +775,8 @@ var lsCommand2 = new Command13("ls").description("list snapshots").option("--jso
686
775
  });
687
776
 
688
777
  // src/commands/snapshots/new.ts
689
- import { Command as Command14 } from "commander";
690
- var newCommand2 = new Command14("new").description("freeze a running box (memory + disk) into a snapshot; the box keeps running").argument("<box>", "box name").argument("<name>", "snapshot name").option("--json", "print the snapshot as JSON").action(async (box, name, opts, cmd) => {
778
+ import { Command as Command16 } from "commander";
779
+ var newCommand2 = new Command16("new").description("freeze a running box (memory + disk) into a snapshot; the box keeps running").argument("<box>", "box name").argument("<name>", "snapshot name").option("--json", "print the snapshot as JSON").action(async (box, name, opts, cmd) => {
691
780
  const client = clientFor(cmd.optsWithGlobals());
692
781
  try {
693
782
  const snap = await client.createSnapshot({ box, name });
@@ -699,8 +788,8 @@ var newCommand2 = new Command14("new").description("freeze a running box (memory
699
788
  });
700
789
 
701
790
  // src/commands/snapshots/rm.ts
702
- import { Command as Command15 } from "commander";
703
- var rmCommand2 = new Command15("rm").description("delete a snapshot (boxes made from it are not affected)").argument("<name>", "snapshot name").option("-y, --yes", "do not ask for confirmation").action(async (name, opts, cmd) => {
791
+ import { Command as Command17 } from "commander";
792
+ var rmCommand2 = new Command17("rm").description("delete a snapshot (boxes made from it are not affected)").argument("<name>", "snapshot name").option("-y, --yes", "do not ask for confirmation").action(async (name, opts, cmd) => {
704
793
  if (!await confirm(`Delete snapshot ${name}?`, opts.yes ?? false)) {
705
794
  info("cancelled");
706
795
  process.exitCode = 1;
@@ -716,11 +805,11 @@ var rmCommand2 = new Command15("rm").description("delete a snapshot (boxes made
716
805
  });
717
806
 
718
807
  // src/commands/snapshots/index.ts
719
- var snapshotsCommand = new Command16("snapshots").aliases(["snapshot", "snap"]).description("freeze running boxes into snapshots and manage them").addCommand(newCommand2).addCommand(lsCommand2).addCommand(rmCommand2);
808
+ var snapshotsCommand = new Command18("snapshots").aliases(["snapshot", "snap"]).description("freeze running boxes into snapshots and manage them").addCommand(newCommand2).addCommand(lsCommand2).addCommand(rmCommand2);
720
809
 
721
810
  // src/program.ts
722
811
  function buildProgram() {
723
- const program = new Command17("kvbox").description("self-hosted Firecracker microVMs with Docker-like ergonomics").version(VERSION, "-v, --version").option("--host <name>", "target a configured remote host (M2)").showHelpAfterError().enablePositionalOptions();
812
+ const program = new Command19("kvbox").description("self-hosted Firecracker microVMs with Docker-like ergonomics").version(VERSION, "-v, --version").option("--host <name>", "target a configured remote host (M2)").showHelpAfterError().enablePositionalOptions();
724
813
  program.addCommand(vmCommand);
725
814
  program.addCommand(snapshotsCommand);
726
815
  program.addCommand(serverCommand);
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/exec.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/snapshots/index.ts","../src/commands/snapshots/ls.ts","../src/commands/snapshots/new.ts","../src/commands/snapshots/rm.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\n// eslint-disable-next-line no-control-regex\nconst ANSI = /\\x1b\\[[0-9;]*m/g;\n/** Printed width of a cell: color codes take no columns. */\nconst width = (s: string) => s.replace(ANSI, \"\").length;\n\n/** Cells may carry color codes; alignment uses the visible text. */\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) => width(r[i]!))));\n const line = (parts: string[]) =>\n parts.map((p, i) => p + \" \".repeat(Math.max(0, widths[i]! - width(p)))).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\n/** Compact byte count for a table cell: \"4GB\", \"3.4GB\", \"640MB\". */\nexport function gbShort(bytes: number): string {\n return gb(bytes).replace(\" \", \"\");\n}\n\n/** \"2×4GB · 8GB disk\": the shape of a box in one cell. */\nexport function shape(vcpu: number, memMib: number, diskBytes?: number): string {\n const cpuRam = `${vcpu}×${gbShort(memMib * 1024 ** 2)}`;\n return diskBytes === undefined ? cpuRam : `${cpuRam} · ${gbShort(diskBytes)} disk`;\n}\n\n/** Box name as it appears in every table: one color, so the eye finds it first. */\nexport function boxName(name: string): string {\n return color.cyan(name);\n}\n\n/** Status word, colored: running green, anything else dim. */\nexport function status(s: string): string {\n return s === \"running\" ? color.green(s) : color.dim(s);\n}\n\n/** How long ago an ISO timestamp was, in docker's style: \"just now\", \"5m ago\", \"2h ago\", \"3d ago\". */\nexport function age(iso: string, now = Date.now()): string {\n const sec = Math.max(0, Math.floor((now - Date.parse(iso)) / 1000));\n if (sec < 60) return \"just now\";\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.floor(hr / 24);\n if (day < 30) return `${day}d ago`;\n const month = Math.floor(day / 30);\n if (month < 12) return `${month}mo ago`;\n return `${Math.floor(day / 365)}y ago`;\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 { snapshotsCommand } from \"./commands/snapshots/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(snapshotsCommand);\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 { execCommand } from \"./exec.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(execCommand)\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, execCommand, stopCommand, startCommand, rmCommand];\n","import { spawnSync } from \"node:child_process\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs, waitForSsh } from \"../../client.js\";\nimport { info } from \"../../output.js\";\n\n/**\n * kvbox vm connect <name> [-- cmd...] — ssh kvbox@<ip> with the kvbox key; a shell, or run a command.\n * A stopped box is started first: \"connect\" means \"get me in\", not \"fail because I forgot start\".\n */\nexport const connectCommand = new Command(\"connect\")\n .alias(\"cn\")\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 let 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 === \"stopped\") {\n info(`box ${name} is stopped; starting it`);\n box = await client.startMachine(name);\n await waitForSsh(box.ip);\n }\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\n/**\n * Resolve once something accepts a TCP connection on `ip`:22, or reject after `timeoutMs`.\n * A freshly started box takes a second or two before sshd listens; ssh itself would just fail.\n */\nexport async function waitForSsh(ip: string, timeoutMs = 30_000): Promise<void> {\n const { connect } = await import(\"node:net\");\n const deadline = Date.now() + timeoutMs;\n const attempt = () =>\n new Promise<boolean>((resolve) => {\n const sock = connect({ host: ip, port: 22, timeout: 1000 });\n sock.once(\"connect\", () => { sock.destroy(); resolve(true); });\n sock.once(\"timeout\", () => { sock.destroy(); resolve(false); });\n sock.once(\"error\", () => resolve(false));\n });\n while (Date.now() < deadline) {\n if (await attempt()) return;\n await new Promise((r) => setTimeout(r, 250));\n }\n throw new KvboxError(`box at ${ip} did not answer on port 22 within ${Math.round(timeoutMs / 1000)}s`);\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(), // the box it was taken from\n base: z.string(), // base image version the overlay stacks on; a restore needs the same one\n vcpu: z.number().int(),\n memMib: z.number().int(),\n sizeBytes: z.number().int(), // what vmstate + mem + overlay really occupy on the host\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 /** Firecracker's snapshot-editor, from the same release: merges a diff snapshot onto a full memory image. */\n snapshotEditor: join(home, \"bin\", \"snapshot-editor\"),\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 /**\n * The box's memory as of its last snapshot (a hard link to that snapshot's `mem`, never modified).\n * The next snapshot is a diff of the pages dirtied since, merged onto this. Absent after a boot.\n */\n memBase: join(home, \"machines\", name, \"mem.base\"),\n sock: join(home, \"machines\", name, \"fc.sock\"),\n /** Firecracker's vsock endpoint: the host connects here to reach kvbox-agent inside the box (core/agent.ts). */\n vsock: join(home, \"machines\", name, \"vsock.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 /** Copy of the box's overlay at the moment of the snapshot; the base image is referenced by version in meta.json. */\n overlay: join(home, \"snapshots\", name, \"overlay.ext4\"),\n }),\n } as const;\n}\n\nexport type Paths = ReturnType<typeof paths>;\n","import { spawn } from \"node:child_process\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs } from \"../../client.js\";\n\n/** POSIX single-quote a string for the guest's shell. */\nexport function shellQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * The one string handed to the guest's login shell: the words after `--` joined with spaces\n * (so `'cd /app && npm test'` and `cd /app '&&' npm test` both work), preceded by `export`s\n * for `--env` so the shell itself expands `$VAR` in the command. SSH SetEnv is not an option:\n * the image's sshd does not AcceptEnv (#24).\n */\nexport function remoteCommand(cmdArgs: string[], env: string[]): string {\n const cmd = cmdArgs.join(\" \");\n if (env.length === 0) return cmd;\n const assignments = env.map((entry) => {\n const eq = entry.indexOf(\"=\");\n const key = eq > 0 ? entry.slice(0, eq) : \"\";\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new KvboxError(`--env ${entry}: expected KEY=VALUE`);\n return `${key}=${shellQuote(entry.slice(eq + 1))}`;\n });\n return `export ${assignments.join(\" \")}; ${cmd}`;\n}\n\n/** `timeout(1)`'s exit status when the command was killed. */\nconst TIMEOUT_EXIT = 124;\n/** ssh's own status when it could not connect or the session broke. */\nconst SSH_FAILED = 255;\n\nfunction collect(value: string, previous: string[] | undefined): string[] {\n return [...(previous ?? []), value];\n}\n\nfunction positiveSeconds(value: string): number {\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) throw new InvalidArgumentError(\"expected a number of seconds > 0\");\n return n;\n}\n\ninterface ExecOptions {\n env?: string[];\n timeout?: number;\n tty?: boolean;\n json?: boolean;\n}\n\n/** kvbox vm exec <name> [-e K=V]... [--timeout N] [--tty] [--json] -- <cmd...> */\nexport const execCommand = new Command(\"exec\")\n .description(\"run a command in a box and exit with its status (kvbox exec <name> -- <cmd>)\")\n .argument(\"<name>\", \"box name\")\n .argument(\"<cmd...>\", \"command, passed to the box's shell as one string (pipes, &&, cd work)\")\n .option(\"-e, --env <KEY=VALUE>\", \"set an environment variable for the command (repeatable)\", collect)\n .option(\"--timeout <seconds>\", \"kill the command after N seconds and exit 124\", positiveSeconds)\n .option(\"--tty\", \"allocate a pseudo-terminal (for interactive tools like htop)\")\n .option(\"--json\", 'capture output and print {\"output\": \"...\", \"exit_code\": N}')\n // No passThroughOptions: flags come after the box name, `--` ends them, the rest is the command.\n .action(async (name: string, cmdArgs: string[], opts: ExecOptions, 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\n const remote = remoteCommand(cmdArgs, opts.env ?? []);\n const stdinIsTty = process.stdin.isTTY === true;\n const ssh = [\n ...(opts.tty ? [\"-t\"] : []),\n // With a terminal on stdin nothing is sent (the command would otherwise wait on it);\n // from a pipe or file, stdin is forwarded and its EOF reaches the command.\n ...(stdinIsTty && !opts.tty ? [\"-n\"] : []),\n ...sshArgs(ip),\n // ssh joins everything after the host into the remote command line.\n remote,\n ];\n\n const child = spawn(\"ssh\", ssh, { stdio: [\"inherit\", opts.json ? \"pipe\" : \"inherit\", opts.json ? \"pipe\" : \"inherit\"] });\n const chunks: Buffer[] = [];\n child.stdout?.on(\"data\", (c: Buffer) => chunks.push(c));\n child.stderr?.on(\"data\", (c: Buffer) => chunks.push(c));\n\n let timedOut = false;\n const timer =\n opts.timeout === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n }, opts.timeout * 1000);\n\n const status = await new Promise<number>((resolve, reject) => {\n child.once(\"error\", (err) => reject(new KvboxError(`could not run ssh: ${err.message}`)));\n child.once(\"close\", (code, signal) => {\n if (timedOut) resolve(TIMEOUT_EXIT);\n else if (code !== null) resolve(code);\n else resolve(signal === \"SIGINT\" ? 130 : 1);\n });\n }).finally(() => clearTimeout(timer));\n\n if (status === SSH_FAILED && !timedOut) {\n if (opts.json) process.stderr.write(Buffer.concat(chunks));\n throw new KvboxError(`box ${name}: could not run the command over SSH (box still booting?)`, SSH_FAILED);\n }\n if (opts.json) {\n process.stdout.write(JSON.stringify({ output: Buffer.concat(chunks).toString(\"utf8\"), exit_code: status }) + \"\\n\");\n }\n process.exit(status);\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { age, boxName, color, gbShort, info, json, shape, status, 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 // Five columns; cpu/ram/disk/source details stay in --json.\n table(\n boxes.map((b) => ({\n name: boxName(b.name),\n status: status(b.status),\n ip: b.ip,\n size: `${shape(b.vcpu, b.memMib, b.diskBytes)} ${color.dim(`(${gbShort(b.diskUsedBytes)} used)`)}`,\n created: age(b.createdAt),\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 if (opts.from !== undefined) info(` connect with: kvbox connect ${box.name} (already up: everything that ran in the snapshot is running)`);\n else 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 const from = box.source.startsWith(\"snapshot:\") ? ` from snapshot ${box.source.slice(\"snapshot:\".length)}` : \"\";\n return `box ${color.bold(box.name)} is ${box.status} at ${box.ip}${from}: ${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 { newCommand } from \"./new.js\";\nimport { rmCommand } from \"./rm.js\";\n\nexport const snapshotsCommand = new Command(\"snapshots\")\n .aliases([\"snapshot\", \"snap\"])\n .description(\"freeze running boxes into snapshots and manage them\")\n .addCommand(newCommand)\n .addCommand(lsCommand)\n .addCommand(rmCommand);\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { age, boxName, gbShort, info, json, shape, table } from \"../../output.js\";\n\n/** kvbox snapshots ls [--json] — --json output: Snapshot[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list snapshots\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const snaps = await client.listSnapshots();\n if (opts.json) {\n json(snaps);\n return;\n }\n if (snaps.length === 0) {\n info(\"no snapshots yet; freeze a running box with: kvbox snapshots new <box> <name>\");\n return;\n }\n // Base image version stays in --json; a restore checks it, a reader rarely needs it.\n table(\n snaps.map((s) => ({\n name: boxName(s.name),\n \"from box\": s.source,\n shape: shape(s.vcpu, s.memMib),\n \"on disk\": gbShort(s.sizeBytes),\n created: age(s.createdAt),\n })),\n );\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, gb, info, json } from \"../../output.js\";\n\n/** kvbox snapshots new <box> <name> [--json] — --json output: Snapshot */\nexport const newCommand = new Command(\"new\")\n .description(\"freeze a running box (memory + disk) into a snapshot; the box keeps running\")\n .argument(\"<box>\", \"box name\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"--json\", \"print the snapshot as JSON\")\n .action(async (box: string, name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const snap = await client.createSnapshot({ box, name });\n if (opts.json) json(snap);\n else info(`${color.green(\"✓\")} snapshot ${name} saved from box ${box} (${gb(snap.sizeBytes)} on disk); start a warm clone with: kvbox new --from ${name}`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, confirm, info } from \"../../output.js\";\n\n/** kvbox snapshots rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"delete a snapshot (boxes made from it are not affected)\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(async (name: string, opts: { yes?: boolean }, cmd: Command) => {\n if (!(await confirm(`Delete snapshot ${name}?`, opts.yes ?? false))) {\n info(\"cancelled\");\n process.exitCode = 1;\n return;\n }\n const client = clientFor(cmd.optsWithGlobals());\n try {\n await client.deleteSnapshot(name);\n info(`${color.green(\"✓\")} snapshot ${name} deleted`);\n } finally {\n await client.close();\n }\n });\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","spawn","Command","Command","spawn","status","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","newCommand","Command","Command","rmCommand","Command","Command","newCommand","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/exec.ts","../src/commands/vm/ls.ts","../src/commands/vm/new.ts","../src/commands/vm/rescale.ts","../src/commands/vm/rm.ts","../src/commands/vm/start.ts","../src/commands/vm/stop.ts","../src/commands/vm/update.ts","../src/commands/server/index.ts","../src/commands/server/start.ts","../src/commands/server/status.ts","../src/commands/server/stop.ts","../src/commands/snapshots/index.ts","../src/commands/snapshots/ls.ts","../src/commands/snapshots/new.ts","../src/commands/snapshots/rm.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\n// eslint-disable-next-line no-control-regex\nconst ANSI = /\\x1b\\[[0-9;]*m/g;\n/** Printed width of a cell: color codes take no columns. */\nconst width = (s: string) => s.replace(ANSI, \"\").length;\n\n/** Cells may carry color codes; alignment uses the visible text. */\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) => width(r[i]!))));\n const line = (parts: string[]) =>\n parts.map((p, i) => p + \" \".repeat(Math.max(0, widths[i]! - width(p)))).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\n/** Compact byte count for a table cell: \"4GB\", \"3.4GB\", \"640MB\". */\nexport function gbShort(bytes: number): string {\n return gb(bytes).replace(\" \", \"\");\n}\n\n/** \"2×4GB · 8GB disk\": the shape of a box in one cell. */\nexport function shape(vcpu: number, memMib: number, diskBytes?: number): string {\n const cpuRam = `${vcpu}×${gbShort(memMib * 1024 ** 2)}`;\n return diskBytes === undefined ? cpuRam : `${cpuRam} · ${gbShort(diskBytes)} disk`;\n}\n\n/** Box name as it appears in every table: one color, so the eye finds it first. */\nexport function boxName(name: string): string {\n return color.cyan(name);\n}\n\n/** Status word, colored: running green, anything else dim. */\nexport function status(s: string): string {\n return s === \"running\" ? color.green(s) : color.dim(s);\n}\n\n/** How long ago an ISO timestamp was, in docker's style: \"just now\", \"5m ago\", \"2h ago\", \"3d ago\". */\nexport function age(iso: string, now = Date.now()): string {\n const sec = Math.max(0, Math.floor((now - Date.parse(iso)) / 1000));\n if (sec < 60) return \"just now\";\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.floor(hr / 24);\n if (day < 30) return `${day}d ago`;\n const month = Math.floor(day / 30);\n if (month < 12) return `${month}mo ago`;\n return `${Math.floor(day / 365)}y ago`;\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 { snapshotsCommand } from \"./commands/snapshots/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(snapshotsCommand);\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 { execCommand } from \"./exec.js\";\nimport { lsCommand } from \"./ls.js\";\nimport { newCommand } from \"./new.js\";\nimport { rescaleCommand } from \"./rescale.js\";\nimport { rmCommand } from \"./rm.js\";\nimport { startCommand } from \"./start.js\";\nimport { stopCommand } from \"./stop.js\";\nimport { updateCommand } from \"./update.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(execCommand)\n .addCommand(stopCommand)\n .addCommand(startCommand)\n .addCommand(updateCommand)\n .addCommand(rescaleCommand)\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, execCommand, stopCommand, startCommand, updateCommand, rescaleCommand, rmCommand];\n","import { spawnSync } from \"node:child_process\";\nimport { Command } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs, waitForSsh } from \"../../client.js\";\nimport { info } from \"../../output.js\";\n\n/**\n * kvbox vm connect <name> [-- cmd...] — ssh kvbox@<ip> with the kvbox key; a shell, or run a command.\n * A stopped box is started first: \"connect\" means \"get me in\", not \"fail because I forgot start\".\n */\nexport const connectCommand = new Command(\"connect\")\n .alias(\"cn\")\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 let 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 === \"stopped\") {\n info(`box ${name} is stopped; starting it`);\n box = await client.startMachine(name);\n await waitForSsh(box.ip);\n }\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 type RescaleMachineRequest,\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 updateMachine(name: string) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/update`, MachineSchema);\n }\n\n rescaleMachine(name: string, req: RescaleMachineRequest) {\n return this.call(\"POST\", `/machines/${encodeURIComponent(name)}/rescale`, MachineSchema, req);\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\n/**\n * Resolve once something accepts a TCP connection on `ip`:22, or reject after `timeoutMs`.\n * A freshly started box takes a second or two before sshd listens; ssh itself would just fail.\n */\nexport async function waitForSsh(ip: string, timeoutMs = 30_000): Promise<void> {\n const { connect } = await import(\"node:net\");\n const deadline = Date.now() + timeoutMs;\n const attempt = () =>\n new Promise<boolean>((resolve) => {\n const sock = connect({ host: ip, port: 22, timeout: 1000 });\n sock.once(\"connect\", () => { sock.destroy(); resolve(true); });\n sock.once(\"timeout\", () => { sock.destroy(); resolve(false); });\n sock.once(\"error\", () => resolve(false));\n });\n while (Date.now() < deadline) {\n if (await attempt()) return;\n await new Promise((r) => setTimeout(r, 250));\n }\n throw new KvboxError(`box at ${ip} did not answer on port 22 within ${Math.round(timeoutMs / 1000)}s`);\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\n/** `kvbox rescale`: a preset and/or explicit values; explicit ones win. Anything omitted stays as it is. */\nexport const RescaleMachineRequest = z.object({\n size: SizeSchema.optional(),\n vcpu: z.number().int().min(1).max(64).optional(),\n memMib: z.number().int().min(256).optional(),\n diskGib: z.number().int().min(1).optional(),\n});\nexport type RescaleMachineRequest = z.infer<typeof RescaleMachineRequest>;\n\nexport const SnapshotSchema = z.object({\n name: z.string(),\n source: z.string(), // the box it was taken from\n base: z.string(), // base image version the overlay stacks on; a restore needs the same one\n vcpu: z.number().int(),\n memMib: z.number().int(),\n sizeBytes: z.number().int(), // what vmstate + mem + overlay really occupy on the host\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/**\n * \"16GB\", \"16G\", \"16\", \"4096MB\", \"4096M\", \"0.5GB\" -> MiB. A bare number is GB: that is how\n * people say it (\"16gb\", \"4 vcpu 16gb\"). Returns undefined when it is not a size.\n */\nexport function parseMib(text: string): number | undefined {\n const m = /^\\s*(\\d+(?:\\.\\d+)?)\\s*([gm]i?b?)?\\s*$/i.exec(text);\n if (!m) return undefined;\n const n = Number(m[1]);\n const unit = (m[2] ?? \"g\").toLowerCase();\n const mib = unit.startsWith(\"m\") ? n : n * 1024;\n return Number.isInteger(mib) && mib > 0 ? mib : undefined;\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 /** Firecracker's snapshot-editor, from the same release: merges a diff snapshot onto a full memory image. */\n snapshotEditor: join(home, \"bin\", \"snapshot-editor\"),\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 /**\n * The box's memory as of its last snapshot (a hard link to that snapshot's `mem`, never modified).\n * The next snapshot is a diff of the pages dirtied since, merged onto this. Absent after a boot.\n */\n memBase: join(home, \"machines\", name, \"mem.base\"),\n sock: join(home, \"machines\", name, \"fc.sock\"),\n /** Firecracker's vsock endpoint: the host connects here to reach kvbox-agent inside the box (core/agent.ts). */\n vsock: join(home, \"machines\", name, \"vsock.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 /** Copy of the box's overlay at the moment of the snapshot; the base image is referenced by version in meta.json. */\n overlay: join(home, \"snapshots\", name, \"overlay.ext4\"),\n }),\n } as const;\n}\n\nexport type Paths = ReturnType<typeof paths>;\n","import { spawn } from \"node:child_process\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor, sshArgs } from \"../../client.js\";\n\n/** POSIX single-quote a string for the guest's shell. */\nexport function shellQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * The one string handed to the guest's login shell: the words after `--` joined with spaces\n * (so `'cd /app && npm test'` and `cd /app '&&' npm test` both work), preceded by `export`s\n * for `--env` so the shell itself expands `$VAR` in the command. SSH SetEnv is not an option:\n * the image's sshd does not AcceptEnv (#24).\n */\nexport function remoteCommand(cmdArgs: string[], env: string[]): string {\n const cmd = cmdArgs.join(\" \");\n if (env.length === 0) return cmd;\n const assignments = env.map((entry) => {\n const eq = entry.indexOf(\"=\");\n const key = eq > 0 ? entry.slice(0, eq) : \"\";\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new KvboxError(`--env ${entry}: expected KEY=VALUE`);\n return `${key}=${shellQuote(entry.slice(eq + 1))}`;\n });\n return `export ${assignments.join(\" \")}; ${cmd}`;\n}\n\n/** `timeout(1)`'s exit status when the command was killed. */\nconst TIMEOUT_EXIT = 124;\n/** ssh's own status when it could not connect or the session broke. */\nconst SSH_FAILED = 255;\n\nfunction collect(value: string, previous: string[] | undefined): string[] {\n return [...(previous ?? []), value];\n}\n\nfunction positiveSeconds(value: string): number {\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) throw new InvalidArgumentError(\"expected a number of seconds > 0\");\n return n;\n}\n\ninterface ExecOptions {\n env?: string[];\n timeout?: number;\n tty?: boolean;\n json?: boolean;\n}\n\n/** kvbox vm exec <name> [-e K=V]... [--timeout N] [--tty] [--json] -- <cmd...> */\nexport const execCommand = new Command(\"exec\")\n .description(\"run a command in a box and exit with its status (kvbox exec <name> -- <cmd>)\")\n .argument(\"<name>\", \"box name\")\n .argument(\"<cmd...>\", \"command, passed to the box's shell as one string (pipes, &&, cd work)\")\n .option(\"-e, --env <KEY=VALUE>\", \"set an environment variable for the command (repeatable)\", collect)\n .option(\"--timeout <seconds>\", \"kill the command after N seconds and exit 124\", positiveSeconds)\n .option(\"--tty\", \"allocate a pseudo-terminal (for interactive tools like htop)\")\n .option(\"--json\", 'capture output and print {\"output\": \"...\", \"exit_code\": N}')\n // No passThroughOptions: flags come after the box name, `--` ends them, the rest is the command.\n .action(async (name: string, cmdArgs: string[], opts: ExecOptions, 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\n const remote = remoteCommand(cmdArgs, opts.env ?? []);\n const stdinIsTty = process.stdin.isTTY === true;\n const ssh = [\n ...(opts.tty ? [\"-t\"] : []),\n // With a terminal on stdin nothing is sent (the command would otherwise wait on it);\n // from a pipe or file, stdin is forwarded and its EOF reaches the command.\n ...(stdinIsTty && !opts.tty ? [\"-n\"] : []),\n ...sshArgs(ip),\n // ssh joins everything after the host into the remote command line.\n remote,\n ];\n\n const child = spawn(\"ssh\", ssh, { stdio: [\"inherit\", opts.json ? \"pipe\" : \"inherit\", opts.json ? \"pipe\" : \"inherit\"] });\n const chunks: Buffer[] = [];\n child.stdout?.on(\"data\", (c: Buffer) => chunks.push(c));\n child.stderr?.on(\"data\", (c: Buffer) => chunks.push(c));\n\n let timedOut = false;\n const timer =\n opts.timeout === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n }, opts.timeout * 1000);\n\n const status = await new Promise<number>((resolve, reject) => {\n child.once(\"error\", (err) => reject(new KvboxError(`could not run ssh: ${err.message}`)));\n child.once(\"close\", (code, signal) => {\n if (timedOut) resolve(TIMEOUT_EXIT);\n else if (code !== null) resolve(code);\n else resolve(signal === \"SIGINT\" ? 130 : 1);\n });\n }).finally(() => clearTimeout(timer));\n\n if (status === SSH_FAILED && !timedOut) {\n if (opts.json) process.stderr.write(Buffer.concat(chunks));\n throw new KvboxError(`box ${name}: could not run the command over SSH (box still booting?)`, SSH_FAILED);\n }\n if (opts.json) {\n process.stdout.write(JSON.stringify({ output: Buffer.concat(chunks).toString(\"utf8\"), exit_code: status }) + \"\\n\");\n }\n process.exit(status);\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { age, boxName, color, gbShort, info, json, shape, status, 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 // Five columns; cpu/ram/disk/source details stay in --json.\n table(\n boxes.map((b) => ({\n name: boxName(b.name),\n status: status(b.status),\n ip: b.ip,\n size: `${shape(b.vcpu, b.memMib, b.diskBytes)} ${color.dim(`(${gbShort(b.diskUsedBytes)} used)`)}`,\n created: age(b.createdAt),\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 if (opts.from !== undefined) info(` connect with: kvbox connect ${box.name} (already up: everything that ran in the snapshot is running)`);\n else 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 const from = box.source.startsWith(\"snapshot:\") ? ` from snapshot ${box.source.slice(\"snapshot:\".length)}` : \"\";\n return `box ${color.bold(box.name)} is ${box.status} at ${box.ip}${from}: ${box.vcpu} vCPU, ${gb(box.memMib * 1024 ** 2)} RAM, ${gb(box.diskBytes)} disk`;\n}\n","import { Command, Option } from \"commander\";\nimport { KvboxError } from \"@kvbox/shared/errors\";\nimport { SIZE_NAMES, parseMib } from \"@kvbox/shared/sizes\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\nimport { describe } from \"./new.js\";\n\n/**\n * kvbox vm rescale <name> [--size s|m|l] [--vcpu N] [--mem 16GB] [--disk 32GB] [--json]\n * --json output: the Machine object. Explicit values override the preset; the disk can only grow.\n * Takes effect at boot: a running box is restarted (files intact, processes gone).\n */\nexport const rescaleCommand = new Command(\"rescale\")\n .description(\"change a box's vCPUs, memory or disk (e.g. --vcpu 4 --mem 16GB); a running box restarts\")\n .argument(\"<name>\", \"box name\")\n .addOption(new Option(\"-s, --size <size>\", \"a preset to start from\").choices(SIZE_NAMES))\n .option(\"--vcpu <n>\", \"number of vCPUs\")\n .option(\"--mem <size>\", \"memory, e.g. 16GB or 4096MB\")\n .option(\"--disk <size>\", \"disk size, e.g. 32GB (grow only)\")\n .option(\"--json\", \"print the box as JSON\")\n .action(async (name: string, opts: { size?: string; vcpu?: string; mem?: string; disk?: string; json?: boolean }, cmd: Command) => {\n const req = {\n ...(opts.size !== undefined ? { size: opts.size } : {}),\n ...(opts.vcpu !== undefined ? { vcpu: parseCount(opts.vcpu) } : {}),\n ...(opts.mem !== undefined ? { memMib: parseSize(\"--mem\", opts.mem) } : {}),\n ...(opts.disk !== undefined ? { diskGib: parseGib(\"--disk\", opts.disk) } : {}),\n };\n if (Object.keys(req).length === 0) throw new KvboxError(\"nothing to change: give --size, --vcpu, --mem or --disk\");\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const before = (await client.listMachines()).find((b) => b.name === name);\n if (!before) throw new KvboxError(`box ${name}: not found (kvbox ls)`);\n const box = await client.rescaleMachine(name, req);\n if (opts.json) {\n json(box);\n return;\n }\n const same = box.vcpu === before.vcpu && box.memMib === before.memMib && box.diskBytes === before.diskBytes;\n if (same) {\n info(`box ${name} already has that shape; nothing changed`);\n return;\n }\n info(`${color.green(\"✓\")} ${describe(box)}`);\n if (before.status === \"running\") info(\" it was restarted: processes that were running are gone, files are intact\");\n } finally {\n await client.close();\n }\n });\n\nfunction parseCount(text: string): number {\n const n = Number(text);\n if (!Number.isInteger(n) || n < 1) throw new KvboxError(`--vcpu ${text}: give a whole number of vCPUs`);\n return n;\n}\n\nfunction parseSize(flag: string, text: string): number {\n const mib = parseMib(text);\n if (mib === undefined) throw new KvboxError(`${flag} ${text}: give a size like 16GB or 4096MB`);\n return mib;\n}\n\nfunction parseGib(flag: string, text: string): number {\n const mib = parseSize(flag, text);\n if (mib % 1024 !== 0) throw new KvboxError(`${flag} ${text}: disk sizes are whole GB`);\n return mib / 1024;\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 { KvboxError } from \"@kvbox/shared/errors\";\nimport { clientFor } from \"../../client.js\";\nimport { color, info, json } from \"../../output.js\";\n\n/**\n * kvbox vm update <name> [--json] — move a box onto the current base image; --json output: the Machine object.\n * The box's own files stay (they live in its overlay); a running box is restarted, so its processes do not.\n * Snapshots are not updated: they are fixed captures. Make a box from one, update it, snapshot again.\n */\nexport const updateCommand = new Command(\"update\")\n .description(\"move a box onto the current base image (its files stay; a running box restarts)\")\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 before = (await client.listMachines()).find((b) => b.name === name);\n if (!before) throw new KvboxError(`box ${name}: not found (kvbox ls)`);\n const box = await client.updateMachine(name);\n if (opts.json) {\n json(box);\n return;\n }\n if (box.base === before.base) {\n info(`box ${name} is already on base image ${box.base}`);\n } else {\n const restarted = before.status === \"running\" ? \" (restarted: processes that were running are gone, files are intact)\" : \"\";\n info(`${color.green(\"✓\")} box ${color.bold(name)} now runs on base image ${box.base} (was ${before.base})${restarted}`);\n }\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 { newCommand } from \"./new.js\";\nimport { rmCommand } from \"./rm.js\";\n\nexport const snapshotsCommand = new Command(\"snapshots\")\n .aliases([\"snapshot\", \"snap\"])\n .description(\"freeze running boxes into snapshots and manage them\")\n .addCommand(newCommand)\n .addCommand(lsCommand)\n .addCommand(rmCommand);\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { age, boxName, gbShort, info, json, shape, table } from \"../../output.js\";\n\n/** kvbox snapshots ls [--json] — --json output: Snapshot[] */\nexport const lsCommand = new Command(\"ls\")\n .description(\"list snapshots\")\n .option(\"--json\", \"print as JSON\")\n .action(async (opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const snaps = await client.listSnapshots();\n if (opts.json) {\n json(snaps);\n return;\n }\n if (snaps.length === 0) {\n info(\"no snapshots yet; freeze a running box with: kvbox snapshots new <box> <name>\");\n return;\n }\n // Base image version stays in --json; a restore checks it, a reader rarely needs it.\n table(\n snaps.map((s) => ({\n name: boxName(s.name),\n \"from box\": s.source,\n shape: shape(s.vcpu, s.memMib),\n \"on disk\": gbShort(s.sizeBytes),\n created: age(s.createdAt),\n })),\n );\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, gb, info, json } from \"../../output.js\";\n\n/** kvbox snapshots new <box> <name> [--json] — --json output: Snapshot */\nexport const newCommand = new Command(\"new\")\n .description(\"freeze a running box (memory + disk) into a snapshot; the box keeps running\")\n .argument(\"<box>\", \"box name\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"--json\", \"print the snapshot as JSON\")\n .action(async (box: string, name: string, opts: { json?: boolean }, cmd: Command) => {\n const client = clientFor(cmd.optsWithGlobals());\n try {\n const snap = await client.createSnapshot({ box, name });\n if (opts.json) json(snap);\n else info(`${color.green(\"✓\")} snapshot ${name} saved from box ${box} (${gb(snap.sizeBytes)} on disk); start a warm clone with: kvbox new --from ${name}`);\n } finally {\n await client.close();\n }\n });\n","import { Command } from \"commander\";\nimport { clientFor } from \"../../client.js\";\nimport { color, confirm, info } from \"../../output.js\";\n\n/** kvbox snapshots rm <name> [-y] — destructive: asks y/N on a TTY, needs -y otherwise */\nexport const rmCommand = new Command(\"rm\")\n .description(\"delete a snapshot (boxes made from it are not affected)\")\n .argument(\"<name>\", \"snapshot name\")\n .option(\"-y, --yes\", \"do not ask for confirmation\")\n .action(async (name: string, opts: { yes?: boolean }, cmd: Command) => {\n if (!(await confirm(`Delete snapshot ${name}?`, opts.yes ?? false))) {\n info(\"cancelled\");\n process.exitCode = 1;\n return;\n }\n const client = clientFor(cmd.optsWithGlobals());\n try {\n await client.deleteSnapshot(name);\n info(`${color.green(\"✓\")} snapshot ${name} deleted`);\n } finally {\n await client.close();\n }\n });\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","spawn","Command","Command","spawn","status","Command","Command","Command","Command","Command","Option","Command","Option","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","newCommand","Command","Command","rmCommand","Command","Command","newCommand","lsCommand","rmCommand","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghalex/kvbox",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
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",