buildwithnexus 0.3.4 → 0.3.5

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
@@ -438,59 +438,59 @@ async function getPortBlocker(port) {
438
438
  return null;
439
439
  }
440
440
  }
441
- async function findFreePort(preferred, max = 20) {
442
- for (let offset = 0; offset < max; offset++) {
443
- if (await isPortFree(preferred + offset)) return preferred + offset;
444
- }
445
- throw new Error(`No free port found near ${preferred}`);
446
- }
447
441
  async function resolvePortConflicts(ports) {
448
442
  const labels = { ssh: "SSH", http: "HTTP", https: "HTTPS" };
449
443
  const resolved = { ...ports };
444
+ const claimed = /* @__PURE__ */ new Set();
450
445
  for (const [key, port] of Object.entries(ports)) {
451
- if (await isPortFree(port)) continue;
452
- const blocker = await getPortBlocker(port);
453
- const desc = blocker ? `${blocker.process} (PID ${blocker.pid})` : "unknown process";
454
- const altPort = await findFreePort(port + 1).catch(() => null);
455
- const choices = [];
456
- if (blocker) {
457
- choices.push({
458
- name: `Kill ${desc} and use port ${port}`,
459
- value: "kill"
460
- });
446
+ if (await isPortFree(port) && !claimed.has(port)) {
447
+ claimed.add(port);
448
+ continue;
449
+ }
450
+ let altPort = null;
451
+ for (let offset = 1; offset <= 50; offset++) {
452
+ const candidate = port + offset;
453
+ if (!claimed.has(candidate) && await isPortFree(candidate)) {
454
+ altPort = candidate;
455
+ break;
456
+ }
461
457
  }
462
458
  if (altPort) {
463
- choices.push({
464
- name: `Use alternate port ${altPort} instead`,
465
- value: "alt"
459
+ resolved[key] = altPort;
460
+ claimed.add(altPort);
461
+ const blocker = await getPortBlocker(port);
462
+ const desc = blocker ? `${blocker.process} (PID ${blocker.pid})` : "another process";
463
+ console.log(chalk5.yellow(` \u26A0 Port ${port} (${labels[key]}) in use by ${desc} \u2192 using ${altPort}`));
464
+ } else {
465
+ const blocker = await getPortBlocker(port);
466
+ const desc = blocker ? `${blocker.process} (PID ${blocker.pid})` : "unknown process";
467
+ console.log("");
468
+ console.log(chalk5.red(` \u2717 Port ${port} (${labels[key]}) is in use by ${desc} and no free port found nearby`));
469
+ const action = await select({
470
+ message: `No free ${labels[key]} port found. Kill ${desc} to free port ${port}?`,
471
+ choices: [
472
+ ...blocker ? [{ name: `Kill ${desc} and use port ${port}`, value: "kill" }] : [],
473
+ { name: "Abort init", value: "abort" }
474
+ ]
466
475
  });
467
- }
468
- choices.push({ name: "Abort init", value: "abort" });
469
- console.log("");
470
- console.log(chalk5.yellow(` \u26A0 Port ${port} (${labels[key]}) is in use by ${desc}`));
471
- const action = await select({
472
- message: `How would you like to resolve the ${labels[key]} port conflict?`,
473
- choices
474
- });
475
- if (action === "kill" && blocker) {
476
- try {
477
- process.kill(blocker.pid, "SIGTERM");
478
- await new Promise((r) => setTimeout(r, 1e3));
479
- if (!await isPortFree(port)) {
480
- process.kill(blocker.pid, "SIGKILL");
481
- await new Promise((r) => setTimeout(r, 500));
476
+ if (action === "kill" && blocker) {
477
+ try {
478
+ process.kill(blocker.pid, "SIGTERM");
479
+ await new Promise((r) => setTimeout(r, 1e3));
480
+ if (!await isPortFree(port)) {
481
+ process.kill(blocker.pid, "SIGKILL");
482
+ await new Promise((r) => setTimeout(r, 500));
483
+ }
484
+ claimed.add(port);
485
+ console.log(chalk5.green(` \u2713 Killed ${desc}, port ${port} is now free`));
486
+ } catch {
487
+ console.log(chalk5.red(` \u2717 Failed to kill PID ${blocker.pid}. Try: sudo kill ${blocker.pid}`));
488
+ process.exit(1);
482
489
  }
483
- console.log(chalk5.green(` \u2713 Killed ${desc}, port ${port} is now free`));
484
- } catch {
485
- console.log(chalk5.red(` \u2717 Failed to kill PID ${blocker.pid}. Try: sudo kill ${blocker.pid}`));
486
- process.exit(1);
490
+ } else {
491
+ console.log(chalk5.dim(" Init aborted."));
492
+ process.exit(0);
487
493
  }
488
- } else if (action === "alt" && altPort) {
489
- resolved[key] = altPort;
490
- console.log(chalk5.green(` \u2713 Using port ${altPort} for ${labels[key]}`));
491
- } else {
492
- console.log(chalk5.dim(" Init aborted."));
493
- process.exit(0);
494
494
  }
495
495
  }
496
496
  return resolved;
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buildwithnexus",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Launch an autonomous AI runtime with triple-nested VM isolation in one command",
5
5
  "type": "module",
6
6
  "bin": {