@novastorm-ai/cli 0.1.0 → 0.1.1

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/nova.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  run
4
- } from "../chunk-QJOSOJPV.js";
5
- import "../chunk-4AQQAQBM.js";
4
+ } from "../chunk-4EPZMOY6.js";
5
+ import "../chunk-KE7XWO5N.js";
6
6
  import "../chunk-QKD6A4EK.js";
7
7
  import "../chunk-KKTDQOQX.js";
8
8
  import "../chunk-3RG5ZIWI.js";
@@ -2,7 +2,7 @@ import {
2
2
  DevServerRunner,
3
3
  ProxyServer,
4
4
  WebSocketServer
5
- } from "./chunk-4AQQAQBM.js";
5
+ } from "./chunk-KE7XWO5N.js";
6
6
  import {
7
7
  ConfigReader,
8
8
  runSetup
@@ -964,7 +964,7 @@ async function startCommand() {
964
964
  projectHash = createHash2("sha256").update(cwd).digest("hex");
965
965
  }
966
966
  const telemetry = new Telemetry();
967
- const cliPkg = await import("./package-GXN6NQIN.js").catch(
967
+ const cliPkg = await import("./package-XCCIIMWT.js").catch(
968
968
  () => ({ default: { version: "0.0.1" } })
969
969
  );
970
970
  telemetry.send({
@@ -1041,7 +1041,7 @@ ${nudgeMessage}
1041
1041
  }
1042
1042
  spinner.succeed("Project indexed.");
1043
1043
  const { ProjectAnalyzer, RagIndexer, createEmbeddingService } = await import("./dist-EMATXD3M.js");
1044
- const { ProjectMapApi } = await import("./dist-6FOBVQ63.js");
1044
+ const { ProjectMapApi } = await import("./dist-5FLNK6MH.js");
1045
1045
  const projectAnalyzer = new ProjectAnalyzer();
1046
1046
  spinner.start("Analyzing project structure...");
1047
1047
  const analysis = await projectAnalyzer.analyze(cwd, projectMap);
@@ -1084,7 +1084,7 @@ ${nudgeMessage}
1084
1084
  ragIndexer = null;
1085
1085
  }
1086
1086
  const projectMapApi = new ProjectMapApi();
1087
- const proxyPort = devPort + PROXY_PORT_OFFSET;
1087
+ let proxyPort = devPort + PROXY_PORT_OFFSET;
1088
1088
  spinner.start("Checking ports...");
1089
1089
  const devPortBusy = await isPortInUse(devPort);
1090
1090
  const proxyPortBusy = await isPortInUse(proxyPort);
@@ -1109,9 +1109,23 @@ ${nudgeMessage}
1109
1109
  await devServer.spawn(devCommand, cwd, devPort);
1110
1110
  } catch (err) {
1111
1111
  spinner.fail("Dev server failed to start.");
1112
- throw err;
1112
+ const msg = err instanceof Error ? err.message : String(err);
1113
+ console.log(chalk6.red(`
1114
+ ${msg}`));
1115
+ console.log(chalk6.gray(`
1116
+ Tips:`));
1117
+ console.log(chalk6.gray(` \u2022 Kill existing process: ${chalk6.cyan(`lsof -ti :${devPort} | xargs kill`)}`));
1118
+ console.log(chalk6.gray(` \u2022 Change port in nova.toml: ${chalk6.cyan(`port = ${devPort + 10}`)}`));
1119
+ process.exit(1);
1120
+ }
1121
+ const actualPort = devServer.getActualPort();
1122
+ if (actualPort && actualPort !== devPort) {
1123
+ spinner.succeed(`Dev server started on port ${chalk6.yellow(actualPort)} (requested ${devPort})`);
1124
+ devPort = actualPort;
1125
+ proxyPort = devPort + PROXY_PORT_OFFSET;
1126
+ } else {
1127
+ spinner.succeed("Dev server started");
1113
1128
  }
1114
- spinner.succeed("Starting dev server... done");
1115
1129
  spinner.start("Starting proxy server...");
1116
1130
  try {
1117
1131
  await proxyServer.start(devPort, proxyPort, OVERLAY_SCRIPT_PATH);
@@ -288,6 +288,15 @@ var WebSocketServer = class {
288
288
  };
289
289
  var POLL_INTERVAL_MS = 500;
290
290
  var MAX_WAIT_MS = 3e4;
291
+ var ERROR_PATTERNS = [
292
+ /port \d+ is in use/i,
293
+ /EADDRINUSE/i,
294
+ /already running/i,
295
+ /address already in use/i,
296
+ /failed to start/i,
297
+ /error:/i
298
+ ];
299
+ var PORT_REDIRECT_PATTERN = /(?:using (?:available )?port|listening on|Local:\s+http:\/\/\S+:)(\d+)/i;
291
300
  var DevServerRunner = class {
292
301
  process = null;
293
302
  logs = [];
@@ -295,30 +304,39 @@ var DevServerRunner = class {
295
304
  readyHandler = null;
296
305
  errorHandler = null;
297
306
  outputHandlers = [];
307
+ detectedPort = null;
308
+ startupError = null;
298
309
  async spawn(command, cwd, port) {
299
310
  const [cmd, ...args] = command.split(" ");
300
311
  this.process = spawn(cmd, args, {
301
312
  cwd,
302
313
  shell: true,
303
314
  stdio: ["ignore", "pipe", "pipe"],
304
- env: { ...process.env }
315
+ env: { ...process.env, PORT: String(port) }
305
316
  });
306
317
  this.running = true;
307
318
  this.logs = [];
308
- this.process.stdout?.on("data", (data) => {
319
+ this.detectedPort = null;
320
+ this.startupError = null;
321
+ const handleOutput = (data) => {
309
322
  const text = data.toString();
310
323
  this.logs.push(text);
311
- for (const handler of this.outputHandlers) {
312
- handler(text);
324
+ const portMatch = PORT_REDIRECT_PATTERN.exec(text);
325
+ if (portMatch) {
326
+ this.detectedPort = parseInt(portMatch[1], 10);
327
+ }
328
+ for (const pattern of ERROR_PATTERNS) {
329
+ if (pattern.test(text)) {
330
+ this.startupError = text.trim();
331
+ break;
332
+ }
313
333
  }
314
- });
315
- this.process.stderr?.on("data", (data) => {
316
- const text = data.toString();
317
- this.logs.push(text);
318
334
  for (const handler of this.outputHandlers) {
319
335
  handler(text);
320
336
  }
321
- });
337
+ };
338
+ this.process.stdout?.on("data", handleOutput);
339
+ this.process.stderr?.on("data", handleOutput);
322
340
  this.process.on("exit", (code, signal) => {
323
341
  this.running = false;
324
342
  if (code !== 0 && code !== null) {
@@ -335,6 +353,12 @@ var DevServerRunner = class {
335
353
  });
336
354
  await this.pollUntilReady(port);
337
355
  }
356
+ getActualPort() {
357
+ return this.detectedPort;
358
+ }
359
+ getStartupError() {
360
+ return this.startupError;
361
+ }
338
362
  onReady(handler) {
339
363
  this.readyHandler = handler;
340
364
  }
@@ -375,40 +399,72 @@ var DevServerRunner = class {
375
399
  if (!this.running) {
376
400
  reject(
377
401
  new Error(
378
- `Dev server process exited before becoming ready. Logs:
402
+ `Dev server process exited before becoming ready.
403
+
379
404
  ${this.getLogs()}`
380
405
  )
381
406
  );
382
407
  return;
383
408
  }
384
- const tryConnect = (host, fallback) => {
385
- const req = http2.get(
386
- `http://${host}:${port}`,
387
- (res) => {
388
- res.resume();
389
- this.readyHandler?.();
390
- resolve();
391
- }
409
+ if (this.startupError) {
410
+ reject(
411
+ new Error(
412
+ `Dev server error:
413
+
414
+ ${this.startupError}`
415
+ )
392
416
  );
393
- req.on("error", () => {
394
- if (fallback) {
395
- tryConnect(fallback);
396
- return;
397
- }
398
- if (Date.now() - startTime >= MAX_WAIT_MS) {
399
- reject(
400
- new Error(
401
- `Dev server did not become ready within ${MAX_WAIT_MS / 1e3}s. Logs:
417
+ return;
418
+ }
419
+ const portsToTry = [port];
420
+ if (this.detectedPort && this.detectedPort !== port) {
421
+ portsToTry.push(this.detectedPort);
422
+ }
423
+ let remaining = portsToTry.length;
424
+ let resolved = false;
425
+ for (const tryPort of portsToTry) {
426
+ const tryConnect = (host, fallback) => {
427
+ if (resolved) return;
428
+ const req = http2.get(
429
+ `http://${host}:${tryPort}`,
430
+ (res) => {
431
+ res.resume();
432
+ if (!resolved) {
433
+ resolved = true;
434
+ if (tryPort !== port) {
435
+ this.detectedPort = tryPort;
436
+ }
437
+ this.readyHandler?.();
438
+ resolve();
439
+ }
440
+ }
441
+ );
442
+ req.on("error", () => {
443
+ if (resolved) return;
444
+ if (fallback) {
445
+ tryConnect(fallback);
446
+ return;
447
+ }
448
+ remaining--;
449
+ if (remaining <= 0) {
450
+ if (Date.now() - startTime >= MAX_WAIT_MS) {
451
+ reject(
452
+ new Error(
453
+ `Dev server did not become ready within ${MAX_WAIT_MS / 1e3}s.
454
+
455
+ Server output:
402
456
  ${this.getLogs()}`
403
- )
404
- );
405
- return;
406
- }
407
- setTimeout(check, POLL_INTERVAL_MS);
408
- });
409
- req.end();
410
- };
411
- tryConnect("127.0.0.1", "[::1]");
457
+ )
458
+ );
459
+ return;
460
+ }
461
+ setTimeout(check, POLL_INTERVAL_MS);
462
+ }
463
+ });
464
+ req.end();
465
+ };
466
+ tryConnect("127.0.0.1", "[::1]");
467
+ }
412
468
  };
413
469
  check();
414
470
  });
@@ -3,7 +3,7 @@ import {
3
3
  ProjectMapApi,
4
4
  ProxyServer,
5
5
  WebSocketServer
6
- } from "./chunk-4AQQAQBM.js";
6
+ } from "./chunk-KE7XWO5N.js";
7
7
  import "./chunk-3RG5ZIWI.js";
8
8
  export {
9
9
  DevServerRunner,
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  createCli,
5
5
  promptAndScaffold,
6
6
  run
7
- } from "./chunk-QJOSOJPV.js";
8
- import "./chunk-4AQQAQBM.js";
7
+ } from "./chunk-4EPZMOY6.js";
8
+ import "./chunk-KE7XWO5N.js";
9
9
  import {
10
10
  ConfigReader,
11
11
  runSetup
@@ -4,7 +4,7 @@ import "./chunk-3RG5ZIWI.js";
4
4
  var package_default = {
5
5
  name: "@novastorm-ai/cli",
6
6
  publishConfig: { access: "public" },
7
- version: "0.1.0",
7
+ version: "0.1.1",
8
8
  license: "SEE LICENSE IN LICENSE.md",
9
9
  type: "module",
10
10
  main: "dist/index.js",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.0",
6
+ "version": "0.1.1",
7
7
  "license": "SEE LICENSE IN LICENSE.md",
8
8
  "type": "module",
9
9
  "main": "dist/index.js",
@@ -35,9 +35,9 @@
35
35
  "devDependencies": {
36
36
  "tsup": "^8.4.0",
37
37
  "typescript": "^5.7.0",
38
- "@novastorm-ai/core": "0.0.1",
39
38
  "@novastorm-ai/licensing": "0.0.1",
40
- "@novastorm-ai/proxy": "0.0.1"
39
+ "@novastorm-ai/proxy": "0.0.1",
40
+ "@novastorm-ai/core": "0.0.1"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "tsup",