gitnexus 1.6.6-rc.23 → 1.6.6-rc.25

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.
@@ -35,7 +35,9 @@ export interface EvalServerOptions {
35
35
  }
36
36
  /**
37
37
  * Validate the --host value. Accepts IPv4, IPv6, or "localhost".
38
- * Returns the normalised host string, or null if invalid.
38
+ * Returns the host string unchanged, or null if invalid.
39
+ * "localhost" is passed through so the OS resolves it to the correct loopback
40
+ * address (127.0.0.1 or ::1) at bind time rather than forcing IPv4.
39
41
  */
40
42
  export declare function validateHost(raw: string): string | null;
41
43
  export declare function formatQueryResult(result: any): string;
@@ -36,11 +36,13 @@ import { logger } from '../core/logger.js';
36
36
  import { cliInfo, cliWarn, cliError } from './cli-message.js';
37
37
  /**
38
38
  * Validate the --host value. Accepts IPv4, IPv6, or "localhost".
39
- * Returns the normalised host string, or null if invalid.
39
+ * Returns the host string unchanged, or null if invalid.
40
+ * "localhost" is passed through so the OS resolves it to the correct loopback
41
+ * address (127.0.0.1 or ::1) at bind time rather than forcing IPv4.
40
42
  */
41
43
  export function validateHost(raw) {
42
44
  if (raw === 'localhost')
43
- return '127.0.0.1';
45
+ return raw;
44
46
  if (isIPv4(raw) || isIPv6(raw))
45
47
  return raw;
46
48
  return null;
@@ -395,11 +397,13 @@ export async function evalServerCommand(options) {
395
397
  ` 2. Use a different port: gitnexus eval-server --port 4849\n`, { code: err.code, port, host });
396
398
  }
397
399
  else if (err.code === 'EADDRNOTAVAIL') {
398
- const isIPv6Host = isIPv6(host);
400
+ // "localhost" may resolve to ::1 on IPv6-only systems; treat it as
401
+ // potentially IPv6 so the user gets the right diagnostic hint.
402
+ const isIPv6Host = isIPv6(host) || host === 'localhost';
399
403
  cliError(`\nGitNexus eval-server failed to start:\n` +
400
404
  ` Address ${host} is not available on this machine.\n\n` +
401
405
  (isIPv6Host
402
- ? ` IPv6 address ${host} is not reachable — IPv6 may be disabled on this system or container.\n` +
406
+ ? ` Address ${host} resolved but is not reachable — IPv6 may be disabled, or the loopback interface may be unavailable.\n` +
403
407
  ` Docker containers and many CI environments disable IPv6 by default.\n\n`
404
408
  : ` The --host value must be an IP assigned to a local network interface.\n` +
405
409
  ` Run \`ip addr\` (Linux) or \`ipconfig\` (Windows) to list available addresses.\n\n`) +
@@ -426,10 +430,19 @@ export async function evalServerCommand(options) {
426
430
  // Plain-text banner for the human watching stderr; structured record
427
431
  // for log aggregation (split into two so the user sees a real banner
428
432
  // not `{"level":30,"msg":"...","port":4747,"endpoints":[...]}`).
429
- // Use server.address().port so --port 0 (OS-assigned) emits the real port.
433
+ // Use server.address() so the banner and READY signal reflect what the OS
434
+ // actually bound to, not the input host string. This matters when "localhost"
435
+ // is passed: the OS may resolve it to ::1 on some systems.
430
436
  const addr = server.address();
431
- const boundPort = typeof addr === 'object' && addr !== null ? addr.port : port;
432
- const displayHost = host.includes(':') ? `[${host}]` : host;
437
+ // server.listen callback only fires after a successful TCP bind, so
438
+ // server.address() is guaranteed to return an AddressInfo object here.
439
+ if (typeof addr !== 'object' || addr === null) {
440
+ cliError(`\nGitNexus eval-server: unexpected server.address() value after bind: ${JSON.stringify(addr)}\n`);
441
+ process.exit(1);
442
+ }
443
+ const boundPort = addr.port;
444
+ const boundAddress = addr.address;
445
+ const displayHost = boundAddress.includes(':') ? `[${boundAddress}]` : boundAddress;
433
446
  const bannerLines = [
434
447
  `GitNexus eval-server: listening on http://${displayHost}:${boundPort}`,
435
448
  ` POST /tool/query — search execution flows`,
@@ -457,8 +470,7 @@ export async function evalServerCommand(options) {
457
470
  });
458
471
  try {
459
472
  // Use fd 1 directly — LadybugDB captures process.stdout (#324)
460
- const readyHost = host.includes(':') ? `[${host}]` : host;
461
- writeSync(1, `GITNEXUS_EVAL_SERVER_READY:${readyHost}:${boundPort}\n`);
473
+ writeSync(1, `GITNEXUS_EVAL_SERVER_READY:${displayHost}:${boundPort}\n`);
462
474
  }
463
475
  catch {
464
476
  // stdout may not be available (e.g., broken pipe)
@@ -48,12 +48,30 @@ export const walkRepositoryPaths = async (repoPath, onProgress) => {
48
48
  }
49
49
  if (skippedLarge > 0) {
50
50
  const isDefault = maxFileSizeBytes === DEFAULT_MAX_FILE_SIZE_BYTES;
51
+ const isOverrideUnset = !process.env.GITNEXUS_MAX_FILE_SIZE;
51
52
  const suffix = isDefault ? ', likely generated/vendored' : '';
52
53
  logger.warn(` Skipped ${skippedLarge} large files (>${maxFileSizeBytes / 1024}KB${suffix})`);
53
- if (isVerboseIngestionEnabled()) {
54
- for (const p of skippedLargePaths) {
55
- logger.warn(` - ${p}`);
56
- }
54
+ // Always show at least the first few paths so users can diagnose why
55
+ // edges are missing from a specific file (issue #1659). The full list is
56
+ // gated behind GITNEXUS_VERBOSE=1 to avoid flooding output on repos with
57
+ // many generated/vendored blobs. Sort before slicing so the preview is
58
+ // stable across runs (fs.stat callbacks race within each batch).
59
+ skippedLargePaths.sort();
60
+ const SKIPPED_PREVIEW_CAP = 5;
61
+ const showAll = isVerboseIngestionEnabled() || skippedLargePaths.length <= SKIPPED_PREVIEW_CAP;
62
+ const preview = showAll ? skippedLargePaths : skippedLargePaths.slice(0, SKIPPED_PREVIEW_CAP);
63
+ for (const p of preview) {
64
+ logger.warn(` - ${p}`);
65
+ }
66
+ if (!showAll) {
67
+ const remaining = skippedLargePaths.length - SKIPPED_PREVIEW_CAP;
68
+ logger.warn(` ...and ${remaining} more (set GITNEXUS_VERBOSE=1 to list them all)`);
69
+ }
70
+ // Only hint about the env var when the user has not set it at all. An
71
+ // explicit GITNEXUS_MAX_FILE_SIZE=512 happens to resolve to the same
72
+ // bytes as the default but the operator clearly already knows the knob.
73
+ if (isDefault && isOverrideUnset) {
74
+ logger.warn(` Set GITNEXUS_MAX_FILE_SIZE=<KB> to include files above the default cap.`);
57
75
  }
58
76
  }
59
77
  return entries;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.6-rc.23",
3
+ "version": "1.6.6-rc.25",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",