buildwithnexus 0.4.5 → 0.4.7
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 +109 -61
- package/package.json +2 -2
- package/dist/nexus-release.tar.gz +0 -0
package/dist/bin.js
CHANGED
|
@@ -18,11 +18,9 @@ __export(banner_exports, {
|
|
|
18
18
|
showSecurityPosture: () => showSecurityPosture
|
|
19
19
|
});
|
|
20
20
|
import chalk from "chalk";
|
|
21
|
-
import { createRequire } from "module";
|
|
22
21
|
function showBanner() {
|
|
23
22
|
console.log(BANNER);
|
|
24
|
-
console.log(chalk.dim(
|
|
25
|
-
`));
|
|
23
|
+
console.log(chalk.dim(" v0.3.1 \xB7 buildwithnexus.dev\n"));
|
|
26
24
|
}
|
|
27
25
|
function showPhase(phase, total, description) {
|
|
28
26
|
const progress = chalk.cyan(`[${phase}/${total}]`);
|
|
@@ -75,12 +73,10 @@ function showCompletion(urls) {
|
|
|
75
73
|
);
|
|
76
74
|
console.log(lines.join("\n"));
|
|
77
75
|
}
|
|
78
|
-
var
|
|
76
|
+
var BANNER;
|
|
79
77
|
var init_banner = __esm({
|
|
80
78
|
"src/ui/banner.ts"() {
|
|
81
79
|
"use strict";
|
|
82
|
-
_require = createRequire(import.meta.url);
|
|
83
|
-
({ version } = _require("../../package.json"));
|
|
84
80
|
BANNER = `
|
|
85
81
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
86
82
|
\u2551 ${chalk.bold.cyan("B U I L D W I T H N E X U S")} \u2551
|
|
@@ -345,9 +341,9 @@ var init_secrets = __esm({
|
|
|
345
341
|
"src/core/secrets.ts"() {
|
|
346
342
|
"use strict";
|
|
347
343
|
init_dlp();
|
|
348
|
-
NEXUS_HOME2 = path2.join(process.env.HOME || "~", ".buildwithnexus");
|
|
349
|
-
CONFIG_PATH = path2.join(NEXUS_HOME2, "config.json");
|
|
350
|
-
KEYS_PATH = path2.join(NEXUS_HOME2, ".env.keys");
|
|
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");
|
|
351
347
|
}
|
|
352
348
|
});
|
|
353
349
|
|
|
@@ -528,10 +524,8 @@ async function launchVm(platform, diskPath, initIsoPath, ram, cpus, ports) {
|
|
|
528
524
|
];
|
|
529
525
|
try {
|
|
530
526
|
await execa(platform.qemuBinary, buildArgs(platform.qemuCpuFlag.split(" ")), { env: scrubEnv() });
|
|
531
|
-
process.stderr.write(" [vm] Hardware acceleration (HVF) active\n");
|
|
532
527
|
} catch {
|
|
533
528
|
const fallbackCpu = platform.os === "mac" ? ["-cpu", "max"] : ["-cpu", "qemu64"];
|
|
534
|
-
process.stderr.write(" [vm] WARNING: HVF unavailable \u2014 using software emulation (VM will be slower)\n");
|
|
535
529
|
await execa(platform.qemuBinary, buildArgs(fallbackCpu), { env: scrubEnv() });
|
|
536
530
|
}
|
|
537
531
|
return ports;
|
|
@@ -677,23 +671,32 @@ function addSshConfig(port) {
|
|
|
677
671
|
fs4.writeFileSync(sshConfigPath, block, { mode: 384 });
|
|
678
672
|
}
|
|
679
673
|
}
|
|
680
|
-
async function waitForSsh(port, timeoutMs =
|
|
674
|
+
async function waitForSsh(port, timeoutMs = 3e5) {
|
|
681
675
|
const start = Date.now();
|
|
676
|
+
let attempt = 0;
|
|
677
|
+
const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
|
|
682
678
|
while (Date.now() - start < timeoutMs) {
|
|
679
|
+
const ssh = new NodeSSH();
|
|
683
680
|
try {
|
|
684
|
-
const ssh = new NodeSSH();
|
|
685
681
|
await ssh.connect({
|
|
686
682
|
host: "localhost",
|
|
687
683
|
port,
|
|
688
684
|
username: "nexus",
|
|
689
685
|
privateKeyPath: SSH_KEY,
|
|
690
|
-
readyTimeout:
|
|
686
|
+
readyTimeout: 5e3,
|
|
691
687
|
hostVerifier: getHostVerifier()
|
|
692
688
|
});
|
|
693
689
|
ssh.dispose();
|
|
694
690
|
return true;
|
|
695
691
|
} catch {
|
|
696
|
-
|
|
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)));
|
|
697
700
|
}
|
|
698
701
|
}
|
|
699
702
|
return false;
|
|
@@ -743,7 +746,6 @@ var init_ssh = __esm({
|
|
|
743
746
|
|
|
744
747
|
// src/cli.ts
|
|
745
748
|
import { Command as Command14 } from "commander";
|
|
746
|
-
import { createRequire as createRequire2 } from "module";
|
|
747
749
|
|
|
748
750
|
// src/commands/init.ts
|
|
749
751
|
init_banner();
|
|
@@ -783,6 +785,13 @@ var log = {
|
|
|
783
785
|
},
|
|
784
786
|
detail(label, value) {
|
|
785
787
|
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");
|
|
786
795
|
}
|
|
787
796
|
};
|
|
788
797
|
|
|
@@ -1024,7 +1033,12 @@ async function checkHealth(port, vmRunning) {
|
|
|
1024
1033
|
sshReady: false,
|
|
1025
1034
|
dockerReady: false,
|
|
1026
1035
|
serverHealthy: false,
|
|
1027
|
-
tunnelUrl: null
|
|
1036
|
+
tunnelUrl: null,
|
|
1037
|
+
dockerVersion: null,
|
|
1038
|
+
serverVersion: null,
|
|
1039
|
+
diskUsagePercent: null,
|
|
1040
|
+
uptimeSeconds: null,
|
|
1041
|
+
lastChecked: (/* @__PURE__ */ new Date()).toISOString()
|
|
1028
1042
|
};
|
|
1029
1043
|
if (!vmRunning) return status;
|
|
1030
1044
|
try {
|
|
@@ -1034,13 +1048,33 @@ async function checkHealth(port, vmRunning) {
|
|
|
1034
1048
|
return status;
|
|
1035
1049
|
}
|
|
1036
1050
|
try {
|
|
1037
|
-
const { code } = await sshExec(port, "docker version --format '{{.Server.Version}}'");
|
|
1038
|
-
status.dockerReady = code === 0;
|
|
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();
|
|
1039
1054
|
} catch {
|
|
1040
1055
|
}
|
|
1041
1056
|
try {
|
|
1042
1057
|
const { stdout, code } = await sshExec(port, "curl -sf http://localhost:4200/health");
|
|
1043
1058
|
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;
|
|
1044
1078
|
} catch {
|
|
1045
1079
|
}
|
|
1046
1080
|
try {
|
|
@@ -1055,6 +1089,8 @@ async function checkHealth(port, vmRunning) {
|
|
|
1055
1089
|
async function waitForServer(port, timeoutMs = 9e5) {
|
|
1056
1090
|
const start = Date.now();
|
|
1057
1091
|
let lastLog = 0;
|
|
1092
|
+
let attempt = 0;
|
|
1093
|
+
const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
|
|
1058
1094
|
while (Date.now() - start < timeoutMs) {
|
|
1059
1095
|
try {
|
|
1060
1096
|
const { stdout, code } = await sshExec(port, "curl -sf http://localhost:4200/health");
|
|
@@ -1072,13 +1108,18 @@ async function waitForServer(port, timeoutMs = 9e5) {
|
|
|
1072
1108
|
} catch {
|
|
1073
1109
|
}
|
|
1074
1110
|
}
|
|
1075
|
-
|
|
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)));
|
|
1076
1115
|
}
|
|
1077
1116
|
return false;
|
|
1078
1117
|
}
|
|
1079
1118
|
async function waitForCloudInit(port, timeoutMs = 18e5) {
|
|
1080
1119
|
const start = Date.now();
|
|
1081
1120
|
let lastLog = 0;
|
|
1121
|
+
let attempt = 0;
|
|
1122
|
+
const backoffMs = (n) => Math.min(3e3 * Math.pow(2, n), 3e4);
|
|
1082
1123
|
while (Date.now() - start < timeoutMs) {
|
|
1083
1124
|
try {
|
|
1084
1125
|
const { code } = await sshExec(port, "test -f /var/lib/cloud/instance/boot-finished");
|
|
@@ -1096,7 +1137,10 @@ async function waitForCloudInit(port, timeoutMs = 18e5) {
|
|
|
1096
1137
|
} catch {
|
|
1097
1138
|
}
|
|
1098
1139
|
}
|
|
1099
|
-
|
|
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)));
|
|
1100
1144
|
}
|
|
1101
1145
|
return false;
|
|
1102
1146
|
}
|
|
@@ -1122,12 +1166,14 @@ async function installCloudflared(sshPort, arch) {
|
|
|
1122
1166
|
].join(" && "));
|
|
1123
1167
|
}
|
|
1124
1168
|
async function startTunnel(sshPort) {
|
|
1125
|
-
await sshExec(
|
|
1126
|
-
|
|
1127
|
-
"
|
|
1128
|
-
|
|
1169
|
+
await sshExec(sshPort, [
|
|
1170
|
+
"install -m 600 /dev/null /home/nexus/.nexus/tunnel.log",
|
|
1171
|
+
"&& nohup cloudflared tunnel --no-autoupdate --url http://localhost:4200",
|
|
1172
|
+
"> /home/nexus/.nexus/tunnel.log 2>&1 &",
|
|
1173
|
+
"disown"
|
|
1174
|
+
].join(" "));
|
|
1129
1175
|
const start = Date.now();
|
|
1130
|
-
while (Date.now() - start <
|
|
1176
|
+
while (Date.now() - start < 6e4) {
|
|
1131
1177
|
try {
|
|
1132
1178
|
const { stdout } = await sshExec(sshPort, "grep -oE 'https://[a-z0-9-]+\\.trycloudflare\\.com' /home/nexus/.nexus/tunnel.log 2>/dev/null | head -1");
|
|
1133
1179
|
if (stdout.includes("https://")) {
|
|
@@ -1160,18 +1206,11 @@ import crypto4 from "crypto";
|
|
|
1160
1206
|
import { fileURLToPath } from "url";
|
|
1161
1207
|
function getReleaseTarball() {
|
|
1162
1208
|
const dir = path6.dirname(fileURLToPath(import.meta.url));
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
// node_modules location (when installed from npm)
|
|
1169
|
-
path6.resolve(dir, "..", "nexus-release.tar.gz")
|
|
1170
|
-
];
|
|
1171
|
-
for (const tarballPath of possiblePaths) {
|
|
1172
|
-
if (fs6.existsSync(tarballPath)) return tarballPath;
|
|
1173
|
-
}
|
|
1174
|
-
throw new Error("nexus-release.tar.gz not found. Run: npm install buildwithnexus@latest");
|
|
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");
|
|
1175
1214
|
}
|
|
1176
1215
|
function getCloudInitTemplate() {
|
|
1177
1216
|
const dir = path6.dirname(fileURLToPath(import.meta.url));
|
|
@@ -1250,11 +1289,6 @@ var phases = [
|
|
|
1250
1289
|
const { config } = ctx;
|
|
1251
1290
|
await withSpinner(spinner, "Generating SSH key...", async () => {
|
|
1252
1291
|
await generateSshKey();
|
|
1253
|
-
const pinFile = path6.join(path6.dirname(getKeyPath()), "vm_host_key.pin");
|
|
1254
|
-
try {
|
|
1255
|
-
fs6.unlinkSync(pinFile);
|
|
1256
|
-
} catch {
|
|
1257
|
-
}
|
|
1258
1292
|
addSshConfig(config.sshPort);
|
|
1259
1293
|
});
|
|
1260
1294
|
}
|
|
@@ -1579,9 +1613,13 @@ var statusCommand = new Command4("status").description("Check NEXUS runtime heal
|
|
|
1579
1613
|
console.log("");
|
|
1580
1614
|
console.log(` ${check(health.vmRunning)} VM ${health.vmRunning ? chalk7.green("running") + chalk7.dim(` (PID ${getVmPid()})`) : chalk7.red("stopped")}`);
|
|
1581
1615
|
console.log(` ${check(health.sshReady)} SSH ${health.sshReady ? chalk7.green("connected") + chalk7.dim(` (port ${config.sshPort})`) : chalk7.red("unreachable")}`);
|
|
1582
|
-
console.log(` ${check(health.dockerReady)} Docker ${health.dockerReady ? chalk7.green("ready") : chalk7.red("not ready")}`);
|
|
1583
|
-
console.log(` ${check(health.serverHealthy)} Server ${health.serverHealthy ? chalk7.green("healthy") + chalk7.dim(` (port ${config.httpPort})`) : chalk7.red("unhealthy")}`);
|
|
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")}`);
|
|
1584
1618
|
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
|
+
}
|
|
1585
1623
|
console.log("");
|
|
1586
1624
|
if (health.serverHealthy) {
|
|
1587
1625
|
log.success(`NEXUS CLI ready \u2014 connect via: buildwithnexus ssh`);
|
|
@@ -1708,18 +1746,11 @@ init_qemu();
|
|
|
1708
1746
|
init_ssh();
|
|
1709
1747
|
function getReleaseTarball2() {
|
|
1710
1748
|
const dir = path9.dirname(fileURLToPath2(import.meta.url));
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
// node_modules location (when installed from npm)
|
|
1717
|
-
path9.resolve(dir, "..", "nexus-release.tar.gz")
|
|
1718
|
-
];
|
|
1719
|
-
for (const tarballPath of possiblePaths) {
|
|
1720
|
-
if (fs8.existsSync(tarballPath)) return tarballPath;
|
|
1721
|
-
}
|
|
1722
|
-
throw new Error("nexus-release.tar.gz not found. Run: npm install buildwithnexus@latest");
|
|
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.");
|
|
1723
1754
|
}
|
|
1724
1755
|
var updateCommand = new Command7("update").description("Update NEXUS to the latest bundled release and restart").action(async () => {
|
|
1725
1756
|
const config = loadConfig();
|
|
@@ -2420,9 +2451,18 @@ var EventStream = class {
|
|
|
2420
2451
|
lastId = "0";
|
|
2421
2452
|
onEvent;
|
|
2422
2453
|
pollInterval = null;
|
|
2454
|
+
consecutiveErrors = 0;
|
|
2455
|
+
lastError = null;
|
|
2423
2456
|
constructor(onEvent) {
|
|
2424
2457
|
this.onEvent = onEvent;
|
|
2425
2458
|
}
|
|
2459
|
+
getStatus() {
|
|
2460
|
+
return {
|
|
2461
|
+
active: this.active,
|
|
2462
|
+
consecutiveErrors: this.consecutiveErrors,
|
|
2463
|
+
lastError: this.lastError
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2426
2466
|
async start() {
|
|
2427
2467
|
this.active = true;
|
|
2428
2468
|
const config = loadConfig();
|
|
@@ -2435,13 +2475,23 @@ var EventStream = class {
|
|
|
2435
2475
|
`curl -sf -H 'Last-Event-ID: ${this.lastId}' http://localhost:4200/events?timeout=1 2>/dev/null || true`
|
|
2436
2476
|
);
|
|
2437
2477
|
if (code === 0 && stdout.trim()) {
|
|
2478
|
+
this.consecutiveErrors = 0;
|
|
2479
|
+
this.lastError = null;
|
|
2438
2480
|
const events = parseSSEData(stdout);
|
|
2439
2481
|
for (const event of events) {
|
|
2440
2482
|
if (event.id) this.lastId = event.id;
|
|
2441
2483
|
this.onEvent(event);
|
|
2442
2484
|
}
|
|
2443
2485
|
}
|
|
2444
|
-
} catch {
|
|
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
|
+
}
|
|
2445
2495
|
}
|
|
2446
2496
|
}, 2e3);
|
|
2447
2497
|
}
|
|
@@ -2856,9 +2906,7 @@ var shellCommand2 = new Command13("shell").description("Launch the interactive N
|
|
|
2856
2906
|
});
|
|
2857
2907
|
|
|
2858
2908
|
// src/cli.ts
|
|
2859
|
-
var
|
|
2860
|
-
var { version: version2 } = _require2("../package.json");
|
|
2861
|
-
var cli = new Command14().name("buildwithnexus").description("Auto-scaffold and launch a fully autonomous NEXUS runtime").version(version2);
|
|
2909
|
+
var cli = new Command14().name("buildwithnexus").description("Auto-scaffold and launch a fully autonomous NEXUS runtime").version("0.3.1");
|
|
2862
2910
|
cli.addCommand(initCommand);
|
|
2863
2911
|
cli.addCommand(startCommand);
|
|
2864
2912
|
cli.addCommand(stopCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "buildwithnexus",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
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"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">=18"
|
|
Binary file
|