buildwithnexus 0.4.0 → 0.4.2

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/bin.js CHANGED
@@ -341,9 +341,9 @@ var init_secrets = __esm({
341
341
  "src/core/secrets.ts"() {
342
342
  "use strict";
343
343
  init_dlp();
344
- NEXUS_HOME2 = process.env.NEXUS_HOME || path2.join(process.env.HOME || "~", ".buildwithnexus");
345
- CONFIG_PATH = process.env.NEXUS_CONFIG_PATH || path2.join(NEXUS_HOME2, "config.json");
346
- KEYS_PATH = process.env.NEXUS_KEYS_PATH || path2.join(NEXUS_HOME2, ".env.keys");
344
+ NEXUS_HOME2 = path2.join(process.env.HOME || "~", ".buildwithnexus");
345
+ CONFIG_PATH = path2.join(NEXUS_HOME2, "config.json");
346
+ KEYS_PATH = path2.join(NEXUS_HOME2, ".env.keys");
347
347
  }
348
348
  });
349
349
 
@@ -673,11 +673,9 @@ function addSshConfig(port) {
673
673
  }
674
674
  async function waitForSsh(port, timeoutMs = 3e5) {
675
675
  const start = Date.now();
676
- let attempt = 0;
677
- const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
678
676
  while (Date.now() - start < timeoutMs) {
679
- const ssh = new NodeSSH();
680
677
  try {
678
+ const ssh = new NodeSSH();
681
679
  await ssh.connect({
682
680
  host: "localhost",
683
681
  port,
@@ -689,14 +687,7 @@ async function waitForSsh(port, timeoutMs = 3e5) {
689
687
  ssh.dispose();
690
688
  return true;
691
689
  } catch {
692
- try {
693
- ssh.dispose();
694
- } catch {
695
- }
696
- const delay = backoffMs(attempt++);
697
- const remaining = timeoutMs - (Date.now() - start);
698
- if (remaining <= 0) break;
699
- await new Promise((r) => setTimeout(r, Math.min(delay, remaining)));
690
+ await new Promise((r) => setTimeout(r, 5e3));
700
691
  }
701
692
  }
702
693
  return false;
@@ -785,13 +776,6 @@ var log = {
785
776
  },
786
777
  detail(label, value) {
787
778
  console.log(chalk3.dim(" " + label + ": ") + value);
788
- },
789
- progress(current, total, label) {
790
- const pct = Math.round(current / total * 100);
791
- const filled = Math.round(current / total * 20);
792
- const bar = chalk3.cyan("\u2588".repeat(filled)) + chalk3.dim("\u2591".repeat(20 - filled));
793
- process.stdout.write(`\r [${bar}] ${chalk3.bold(`${pct}%`)} ${chalk3.dim(label)}`);
794
- if (current >= total) process.stdout.write("\n");
795
779
  }
796
780
  };
797
781
 
@@ -1033,12 +1017,7 @@ async function checkHealth(port, vmRunning) {
1033
1017
  sshReady: false,
1034
1018
  dockerReady: false,
1035
1019
  serverHealthy: false,
1036
- tunnelUrl: null,
1037
- dockerVersion: null,
1038
- serverVersion: null,
1039
- diskUsagePercent: null,
1040
- uptimeSeconds: null,
1041
- lastChecked: (/* @__PURE__ */ new Date()).toISOString()
1020
+ tunnelUrl: null
1042
1021
  };
1043
1022
  if (!vmRunning) return status;
1044
1023
  try {
@@ -1048,33 +1027,13 @@ async function checkHealth(port, vmRunning) {
1048
1027
  return status;
1049
1028
  }
1050
1029
  try {
1051
- const { stdout, code } = await sshExec(port, "docker version --format '{{.Server.Version}}'");
1052
- status.dockerReady = code === 0 && stdout.trim().length > 0;
1053
- if (status.dockerReady) status.dockerVersion = stdout.trim();
1030
+ const { code } = await sshExec(port, "docker version --format '{{.Server.Version}}'");
1031
+ status.dockerReady = code === 0;
1054
1032
  } catch {
1055
1033
  }
1056
1034
  try {
1057
1035
  const { stdout, code } = await sshExec(port, "curl -sf http://localhost:4200/health");
1058
1036
  status.serverHealthy = code === 0 && stdout.includes("ok");
1059
- if (status.serverHealthy) {
1060
- try {
1061
- const parsed = JSON.parse(stdout);
1062
- if (typeof parsed.version === "string") status.serverVersion = parsed.version;
1063
- } catch {
1064
- }
1065
- }
1066
- } catch {
1067
- }
1068
- try {
1069
- const { stdout } = await sshExec(port, "df / --output=pcent | tail -1 | tr -dc '0-9'");
1070
- const pct = parseInt(stdout.trim(), 10);
1071
- if (!isNaN(pct)) status.diskUsagePercent = pct;
1072
- } catch {
1073
- }
1074
- try {
1075
- const { stdout } = await sshExec(port, "awk '{print int($1)}' /proc/uptime 2>/dev/null");
1076
- const up = parseInt(stdout.trim(), 10);
1077
- if (!isNaN(up)) status.uptimeSeconds = up;
1078
1037
  } catch {
1079
1038
  }
1080
1039
  try {
@@ -1089,8 +1048,6 @@ async function checkHealth(port, vmRunning) {
1089
1048
  async function waitForServer(port, timeoutMs = 9e5) {
1090
1049
  const start = Date.now();
1091
1050
  let lastLog = 0;
1092
- let attempt = 0;
1093
- const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
1094
1051
  while (Date.now() - start < timeoutMs) {
1095
1052
  try {
1096
1053
  const { stdout, code } = await sshExec(port, "curl -sf http://localhost:4200/health");
@@ -1108,18 +1065,13 @@ async function waitForServer(port, timeoutMs = 9e5) {
1108
1065
  } catch {
1109
1066
  }
1110
1067
  }
1111
- const delay = backoffMs(attempt++);
1112
- const remaining = timeoutMs - (Date.now() - start);
1113
- if (remaining <= 0) break;
1114
- await new Promise((r) => setTimeout(r, Math.min(delay, remaining)));
1068
+ await new Promise((r) => setTimeout(r, 5e3));
1115
1069
  }
1116
1070
  return false;
1117
1071
  }
1118
1072
  async function waitForCloudInit(port, timeoutMs = 18e5) {
1119
1073
  const start = Date.now();
1120
1074
  let lastLog = 0;
1121
- let attempt = 0;
1122
- const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
1123
1075
  while (Date.now() - start < timeoutMs) {
1124
1076
  try {
1125
1077
  const { code } = await sshExec(port, "test -f /var/lib/cloud/instance/boot-finished");
@@ -1137,10 +1089,7 @@ async function waitForCloudInit(port, timeoutMs = 18e5) {
1137
1089
  } catch {
1138
1090
  }
1139
1091
  }
1140
- const delay = backoffMs(attempt++);
1141
- const remaining = timeoutMs - (Date.now() - start);
1142
- if (remaining <= 0) break;
1143
- await new Promise((r) => setTimeout(r, Math.min(delay, remaining)));
1092
+ await new Promise((r) => setTimeout(r, 2e4));
1144
1093
  }
1145
1094
  return false;
1146
1095
  }
@@ -1206,11 +1155,18 @@ import crypto4 from "crypto";
1206
1155
  import { fileURLToPath } from "url";
1207
1156
  function getReleaseTarball() {
1208
1157
  const dir = path6.dirname(fileURLToPath(import.meta.url));
1209
- const tarballPath = path6.join(dir, "nexus-release.tar.gz");
1210
- if (fs6.existsSync(tarballPath)) return tarballPath;
1211
- const rootPath = path6.resolve(dir, "..", "dist", "nexus-release.tar.gz");
1212
- if (fs6.existsSync(rootPath)) return rootPath;
1213
- throw new Error("nexus-release.tar.gz not found. Run: npm run bundle");
1158
+ const possiblePaths = [
1159
+ // Current directory (dev)
1160
+ path6.join(dir, "nexus-release.tar.gz"),
1161
+ // dist folder (when built)
1162
+ path6.resolve(dir, "..", "dist", "nexus-release.tar.gz"),
1163
+ // node_modules location (when installed from npm)
1164
+ path6.resolve(dir, "..", "nexus-release.tar.gz")
1165
+ ];
1166
+ for (const tarballPath of possiblePaths) {
1167
+ if (fs6.existsSync(tarballPath)) return tarballPath;
1168
+ }
1169
+ throw new Error("nexus-release.tar.gz not found. Run: npm install buildwithnexus@latest");
1214
1170
  }
1215
1171
  function getCloudInitTemplate() {
1216
1172
  const dir = path6.dirname(fileURLToPath(import.meta.url));
@@ -1613,13 +1569,9 @@ var statusCommand = new Command4("status").description("Check NEXUS runtime heal
1613
1569
  console.log("");
1614
1570
  console.log(` ${check(health.vmRunning)} VM ${health.vmRunning ? chalk7.green("running") + chalk7.dim(` (PID ${getVmPid()})`) : chalk7.red("stopped")}`);
1615
1571
  console.log(` ${check(health.sshReady)} SSH ${health.sshReady ? chalk7.green("connected") + chalk7.dim(` (port ${config.sshPort})`) : chalk7.red("unreachable")}`);
1616
- console.log(` ${check(health.dockerReady)} Docker ${health.dockerReady ? chalk7.green("ready") + (health.dockerVersion ? chalk7.dim(` v${health.dockerVersion}`) : "") : chalk7.red("not ready")}`);
1617
- console.log(` ${check(health.serverHealthy)} Server ${health.serverHealthy ? chalk7.green("healthy") + chalk7.dim(` (port ${config.httpPort})`) + (health.serverVersion ? chalk7.dim(` v${health.serverVersion}`) : "") : chalk7.red("unhealthy")}`);
1572
+ console.log(` ${check(health.dockerReady)} Docker ${health.dockerReady ? chalk7.green("ready") : chalk7.red("not ready")}`);
1573
+ console.log(` ${check(health.serverHealthy)} Server ${health.serverHealthy ? chalk7.green("healthy") + chalk7.dim(` (port ${config.httpPort})`) : chalk7.red("unhealthy")}`);
1618
1574
  console.log(` ${check(!!health.tunnelUrl)} Tunnel ${health.tunnelUrl ? chalk7.green(health.tunnelUrl) : chalk7.dim("not active")}`);
1619
- if (health.diskUsagePercent !== null) {
1620
- const diskOk = health.diskUsagePercent < 85;
1621
- console.log(` ${check(diskOk)} Disk ${diskOk ? chalk7.green(`${health.diskUsagePercent}% used`) : chalk7.yellow(`${health.diskUsagePercent}% used \u2014 consider cleanup`)}`);
1622
- }
1623
1575
  console.log("");
1624
1576
  if (health.serverHealthy) {
1625
1577
  log.success(`NEXUS CLI ready \u2014 connect via: buildwithnexus ssh`);
@@ -1746,11 +1698,18 @@ init_qemu();
1746
1698
  init_ssh();
1747
1699
  function getReleaseTarball2() {
1748
1700
  const dir = path9.dirname(fileURLToPath2(import.meta.url));
1749
- const tarballPath = path9.join(dir, "nexus-release.tar.gz");
1750
- if (fs8.existsSync(tarballPath)) return tarballPath;
1751
- const rootPath = path9.resolve(dir, "..", "dist", "nexus-release.tar.gz");
1752
- if (fs8.existsSync(rootPath)) return rootPath;
1753
- throw new Error("nexus-release.tar.gz not found. Reinstall buildwithnexus to get the latest release.");
1701
+ const possiblePaths = [
1702
+ // Current directory (dev)
1703
+ path9.join(dir, "nexus-release.tar.gz"),
1704
+ // dist folder (when built)
1705
+ path9.resolve(dir, "..", "dist", "nexus-release.tar.gz"),
1706
+ // node_modules location (when installed from npm)
1707
+ path9.resolve(dir, "..", "nexus-release.tar.gz")
1708
+ ];
1709
+ for (const tarballPath of possiblePaths) {
1710
+ if (fs8.existsSync(tarballPath)) return tarballPath;
1711
+ }
1712
+ throw new Error("nexus-release.tar.gz not found. Run: npm install buildwithnexus@latest");
1754
1713
  }
1755
1714
  var updateCommand = new Command7("update").description("Update NEXUS to the latest bundled release and restart").action(async () => {
1756
1715
  const config = loadConfig();
@@ -2451,18 +2410,9 @@ var EventStream = class {
2451
2410
  lastId = "0";
2452
2411
  onEvent;
2453
2412
  pollInterval = null;
2454
- consecutiveErrors = 0;
2455
- lastError = null;
2456
2413
  constructor(onEvent) {
2457
2414
  this.onEvent = onEvent;
2458
2415
  }
2459
- getStatus() {
2460
- return {
2461
- active: this.active,
2462
- consecutiveErrors: this.consecutiveErrors,
2463
- lastError: this.lastError
2464
- };
2465
- }
2466
2416
  async start() {
2467
2417
  this.active = true;
2468
2418
  const config = loadConfig();
@@ -2475,23 +2425,13 @@ var EventStream = class {
2475
2425
  `curl -sf -H 'Last-Event-ID: ${this.lastId}' http://localhost:4200/events?timeout=1 2>/dev/null || true`
2476
2426
  );
2477
2427
  if (code === 0 && stdout.trim()) {
2478
- this.consecutiveErrors = 0;
2479
- this.lastError = null;
2480
2428
  const events = parseSSEData(stdout);
2481
2429
  for (const event of events) {
2482
2430
  if (event.id) this.lastId = event.id;
2483
2431
  this.onEvent(event);
2484
2432
  }
2485
2433
  }
2486
- } catch (err) {
2487
- this.consecutiveErrors++;
2488
- this.lastError = err instanceof Error ? err.message : String(err);
2489
- if (this.consecutiveErrors >= 5) {
2490
- this.onEvent({
2491
- type: "error",
2492
- content: `Event stream disconnected after ${this.consecutiveErrors} attempts: ${this.lastError}`
2493
- });
2494
- }
2434
+ } catch {
2495
2435
  }
2496
2436
  }, 2e3);
2497
2437
  }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buildwithnexus",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Launch an autonomous AI runtime with triple-nested VM isolation in one command",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,7 @@
19
19
  "test": "vitest run",
20
20
  "test:watch": "vitest",
21
21
  "test:coverage": "vitest run --coverage",
22
- "prepublishOnly": "npm run build"
22
+ "prepublishOnly": "npm run build && NEXUS_SRC=/Users/garretteaglin/Projects/nexus npm run bundle"
23
23
  },
24
24
  "engines": {
25
25
  "node": ">=18"