gitnexus 1.6.13-rc.91 → 1.6.13-rc.92

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.
@@ -91,12 +91,12 @@ export declare const processRoutesFromExtracted: (graph: KnowledgeGraph, extract
91
91
  * `handlerName` (the decorated method, captured at extraction); resolve it
92
92
  * directly in the route's own file.
93
93
  *
94
- * First-writer-wins per route identity, matching the routes phase's dedup (it
95
- * keeps the first route registered for a `(method, url)` key and counts the rest
96
- * as duplicates). The first route to claim a key reserves it **even when its
97
- * handler is unresolvable**, so a later same-key route can never stamp its
98
- * handler onto the first route's Route node (the routes phase made that first
99
- * route the node-winner). Keying is `routeNodeKey(method, url)` (#2289): a
94
+ * Production declarations take precedence over test declarations; equal-priority
95
+ * candidates remain first-writer-wins. The selected declaration reserves its key **even when its
96
+ * handler is unresolvable**, so a losing route can never donate its handler.
97
+ * When supplied, `selectedRoutes` receives the admitted winners for the routes
98
+ * phase, keeping node provenance and handler provenance identical.
99
+ * Keying is `routeNodeKey(method, url)` (#2289): a
100
100
  * same-URL multi-verb pair (`GET /x` + `POST /x`) resolves two handlers, one per
101
101
  * node; method-less / wildcard routes key by URL alone, byte-identical to the
102
102
  * pre-#2289 behavior. Routes whose handler cannot be *uniquely* resolved (no
@@ -104,7 +104,7 @@ export declare const processRoutesFromExtracted: (graph: KnowledgeGraph, extract
104
104
  * `handlerSymbolId`; the extractor then falls back to source scan for that route
105
105
  * (fail-open, no regression, never a wrong handler).
106
106
  */
107
- export declare function resolveRouteHandlerSymbols(model: SemanticModel, extractedRoutes: readonly ExtractedRoute[], decoratorRoutes: readonly ExtractedDecoratorRoute[], routeContext?: RouteHandlerResolutionContext): Map<string, string>;
107
+ export declare function resolveRouteHandlerSymbols(model: SemanticModel, extractedRoutes: readonly ExtractedRoute[], decoratorRoutes: readonly ExtractedDecoratorRoute[], routeContext?: RouteHandlerResolutionContext, selectedRoutes?: Set<ExtractedRoute | ExtractedDecoratorRoute>): Map<string, string>;
108
108
  /**
109
109
  * Extract property access keys from a consumer file's source code near fetch calls.
110
110
  *
@@ -17,9 +17,10 @@
17
17
  import { generateId } from '../../lib/utils.js';
18
18
  import { yieldToEventLoop } from './utils/event-loop.js';
19
19
  import { normalizeFetchURL, routeMatches } from './route-extractors/nextjs.js';
20
- import { normalizeExtractedRoutePath, normalizeRouteMethod, routeNodeKey, } from './route-extractors/route-path.js';
20
+ import { isTestRouteFile, normalizeExtractedRoutePath, normalizeRouteMethod, routeNodeKey, } from './route-extractors/route-path.js';
21
21
  import { extractReturnTypeName } from './type-extractors/shared.js';
22
22
  import { DATA_ROUTE_TABLE_SOURCE } from './route-extractors/data-route-table.js';
23
+ import { reconcileDispatchGuardRoutes } from './route-extractors/dispatch-guard.js';
23
24
  import { toZeroBasedLine } from './utils/line-base.js';
24
25
  const MAX_EXPORTS_PER_FILE = 500;
25
26
  const MAX_TYPE_NAME_LENGTH = 256;
@@ -292,12 +293,12 @@ export const processRoutesFromExtracted = async (graph, extractedRoutes, model,
292
293
  * `handlerName` (the decorated method, captured at extraction); resolve it
293
294
  * directly in the route's own file.
294
295
  *
295
- * First-writer-wins per route identity, matching the routes phase's dedup (it
296
- * keeps the first route registered for a `(method, url)` key and counts the rest
297
- * as duplicates). The first route to claim a key reserves it **even when its
298
- * handler is unresolvable**, so a later same-key route can never stamp its
299
- * handler onto the first route's Route node (the routes phase made that first
300
- * route the node-winner). Keying is `routeNodeKey(method, url)` (#2289): a
296
+ * Production declarations take precedence over test declarations; equal-priority
297
+ * candidates remain first-writer-wins. The selected declaration reserves its key **even when its
298
+ * handler is unresolvable**, so a losing route can never donate its handler.
299
+ * When supplied, `selectedRoutes` receives the admitted winners for the routes
300
+ * phase, keeping node provenance and handler provenance identical.
301
+ * Keying is `routeNodeKey(method, url)` (#2289): a
301
302
  * same-URL multi-verb pair (`GET /x` + `POST /x`) resolves two handlers, one per
302
303
  * node; method-less / wildcard routes key by URL alone, byte-identical to the
303
304
  * pre-#2289 behavior. Routes whose handler cannot be *uniquely* resolved (no
@@ -305,12 +306,10 @@ export const processRoutesFromExtracted = async (graph, extractedRoutes, model,
305
306
  * `handlerSymbolId`; the extractor then falls back to source scan for that route
306
307
  * (fail-open, no regression, never a wrong handler).
307
308
  */
308
- export function resolveRouteHandlerSymbols(model, extractedRoutes, decoratorRoutes, routeContext) {
309
+ export function resolveRouteHandlerSymbols(model, extractedRoutes, decoratorRoutes, routeContext, selectedRoutes) {
309
310
  const out = new Map();
310
- // Route identities already claimed by an earlier route (resolved or not).
311
- // Mirrors the routes phase `addRoute` first-writer-wins so the handler we
312
- // stamp always belongs to the route that actually won the Route node.
313
- const claimed = new Set();
311
+ const claimed = new Map();
312
+ const admittedDecoratorRoutes = reconcileDispatchGuardRoutes(decoratorRoutes);
314
313
  // Resolve a single same-file symbol by name. Exactly one match → its nodeId.
315
314
  // Zero or many matches → undefined (fail-open). tRPC same-name handlers
316
315
  // use pickSameFileHandler at the controller-less call site instead.
@@ -386,21 +385,29 @@ export function resolveRouteHandlerSymbols(model, extractedRoutes, decoratorRout
386
385
  ? undefined
387
386
  : uniqueById(model.methods.lookupAllByOwner(owner.nodeId, member))?.nodeId;
388
387
  };
389
- const claim = (routePath, prefix, httpMethod, symbolId) => {
388
+ const claim = (route, symbolId) => {
390
389
  // An empty path is a valid, pathless mapping and normalizes to either `/`
391
390
  // or its class/router prefix. Only null means the extractor had no route.
392
- if (routePath === null)
391
+ if (route.routePath === null)
393
392
  return;
394
- const url = normalizeExtractedRoutePath(routePath, prefix);
395
- const key = routeNodeKey(normalizeRouteMethod(httpMethod), url);
396
- if (claimed.has(key))
397
- return; // first-writer-wins: later same-key routes can't override
398
- claimed.add(key);
393
+ const url = normalizeExtractedRoutePath(route.routePath, route.prefix ?? null);
394
+ const key = routeNodeKey(normalizeRouteMethod(route.httpMethod), url);
395
+ const previous = claimed.get(key);
396
+ if (previous && (!isTestRouteFile(previous.filePath) || isTestRouteFile(route.filePath)))
397
+ return;
398
+ if (previous)
399
+ selectedRoutes?.delete(previous);
400
+ claimed.set(key, route);
401
+ selectedRoutes?.add(route);
402
+ out.delete(key);
399
403
  if (symbolId)
400
404
  out.set(key, symbolId);
401
405
  };
402
406
  // Laravel framework routes — controller class + method name.
403
407
  for (const route of extractedRoutes) {
408
+ // Match the routes phase's admission rule for extracted declarations.
409
+ if (!route.routePath)
410
+ continue;
404
411
  let methodId;
405
412
  if (route.controllerName && route.methodName) {
406
413
  let controllerDef;
@@ -418,16 +425,21 @@ export function resolveRouteHandlerSymbols(model, extractedRoutes, decoratorRout
418
425
  else if (!route.controllerName && route.methodName) {
419
426
  methodId = pickSameFileHandler(model.symbols.lookupExactAll(route.filePath, route.methodName), route, routeContext?.nodeStartLine)?.nodeId;
420
427
  }
421
- claim(route.routePath, route.prefix ?? null, route.httpMethod, methodId);
428
+ claim(route, methodId);
422
429
  }
423
430
  const dataHandlerByRoute = new Map();
424
431
  const dataHandlersByIdentity = new Map();
425
- for (const dr of decoratorRoutes) {
432
+ const dataIdentity = (dr) => {
433
+ const url = normalizeExtractedRoutePath(dr.routePath, dr.prefix ?? null);
434
+ return `${Number(isTestRouteFile(dr.filePath))}:${routeNodeKey(normalizeRouteMethod(dr.httpMethod), url)}`;
435
+ };
436
+ for (const dr of admittedDecoratorRoutes) {
426
437
  if (dr.source !== DATA_ROUTE_TABLE_SOURCE || !dr.handlerName || !dr.routePath)
427
438
  continue;
428
439
  const handlerId = resolveDataRouteHandler(dr.filePath, dr.handlerName);
429
- const url = normalizeExtractedRoutePath(dr.routePath, dr.prefix ?? null);
430
- const key = routeNodeKey(normalizeRouteMethod(dr.httpMethod), url);
440
+ // Conflicting test handlers must not invalidate a production table.
441
+ // Ambiguity is still rejected within each priority tier.
442
+ const key = dataIdentity(dr);
431
443
  const state = dataHandlersByIdentity.get(key) ?? {
432
444
  handlers: new Set(),
433
445
  hasUnresolved: false,
@@ -463,20 +475,18 @@ export function resolveRouteHandlerSymbols(model, extractedRoutes, decoratorRout
463
475
  // handlers. Data tables additionally suppress an identity when duplicate
464
476
  // entries resolve to different handlers: recording either one would invent a
465
477
  // single-winner dispatch that the loop does not prove.
466
- for (const dr of decoratorRoutes) {
478
+ for (const dr of admittedDecoratorRoutes) {
467
479
  const handlerId = decoratorHandlerId(dr);
468
480
  // An unproven data-table entry never becomes a Route node, so it must not
469
481
  // reserve the identity and suppress a later, valid framework declaration.
470
482
  if (dr.source === DATA_ROUTE_TABLE_SOURCE && handlerId === undefined)
471
483
  continue;
472
484
  if (dr.source === DATA_ROUTE_TABLE_SOURCE && dr.routePath) {
473
- const url = normalizeExtractedRoutePath(dr.routePath, dr.prefix ?? null);
474
- const key = routeNodeKey(normalizeRouteMethod(dr.httpMethod), url);
475
- const state = dataHandlersByIdentity.get(key);
485
+ const state = dataHandlersByIdentity.get(dataIdentity(dr));
476
486
  if (state === undefined || state.hasUnresolved || state.handlers.size !== 1)
477
487
  continue;
478
488
  }
479
- claim(dr.routePath, dr.prefix ?? null, dr.httpMethod, handlerId);
489
+ claim(dr, handlerId);
480
490
  }
481
491
  return out;
482
492
  }
@@ -68,6 +68,7 @@ export declare function runChunkedParseAndResolve(graph: KnowledgeGraph, scanned
68
68
  allFetchWrapperDefs: FetchWrapperDef[];
69
69
  allExtractedRoutes: ExtractedRoute[];
70
70
  allDecoratorRoutes: ExtractedDecoratorRoute[];
71
+ selectedRoutes: ReadonlySet<ExtractedRoute | ExtractedDecoratorRoute>;
71
72
  allToolDefs: ExtractedToolDef[];
72
73
  allORMQueries: ExtractedORMQuery[];
73
74
  bindingAccumulator: BindingAccumulator;
@@ -1553,6 +1553,7 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
1553
1553
  parsedImports: parsed.parsedImports.map((parsedImport) => resolveBinding(parsedImport, () => resolveRouteImportTargets(parsedImport, parsed.filePath), routeSourceTextFor)),
1554
1554
  };
1555
1555
  });
1556
+ const selectedRoutes = new Set();
1556
1557
  const routeHandlerSymbols = resolveRouteHandlerSymbols(model, allExtractedRoutes, allDecoratorRoutes, {
1557
1558
  files: routeResolutionFiles,
1558
1559
  resolveImportTarget: resolveRouteImportTarget,
@@ -1563,13 +1564,14 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
1563
1564
  const n = graph.getNode(id);
1564
1565
  return typeof n?.properties.startLine === 'number' ? n.properties.startLine : undefined;
1565
1566
  },
1566
- });
1567
+ }, selectedRoutes);
1567
1568
  return {
1568
1569
  exportedTypeMap,
1569
1570
  allFetchCalls,
1570
1571
  allFetchWrapperDefs,
1571
1572
  allExtractedRoutes,
1572
1573
  allDecoratorRoutes,
1574
+ selectedRoutes,
1573
1575
  allToolDefs,
1574
1576
  allORMQueries,
1575
1577
  bindingAccumulator,
@@ -38,6 +38,8 @@ export interface ParseOutput {
38
38
  readonly allFetchWrapperDefs: readonly FetchWrapperDef[];
39
39
  readonly allExtractedRoutes: readonly ExtractedRoute[];
40
40
  readonly allDecoratorRoutes: readonly ExtractedDecoratorRoute[];
41
+ /** Exact admitted declarations that own Route nodes and handler attribution. */
42
+ readonly selectedRoutes: ReadonlySet<ExtractedRoute | ExtractedDecoratorRoute>;
41
43
  readonly allToolDefs: readonly ExtractedToolDef[];
42
44
  readonly allORMQueries: readonly ExtractedORMQuery[];
43
45
  /** Route URL → resolved handler symbol UID (Part 2, #2138). Consumed by the
@@ -109,7 +109,7 @@ export const routesPhase = {
109
109
  name: 'routes',
110
110
  deps: ['parse'],
111
111
  async execute(ctx, deps) {
112
- const { allPaths, allFetchCalls: parseFetchCalls, allFetchWrapperDefs, allExtractedRoutes, allDecoratorRoutes, routeHandlerSymbols, } = getPhaseOutput(deps, 'parse');
112
+ const { allPaths, allFetchCalls: parseFetchCalls, allFetchWrapperDefs, allExtractedRoutes, allDecoratorRoutes, routeHandlerSymbols, selectedRoutes, } = getPhaseOutput(deps, 'parse');
113
113
  // Local copy — routes phase must not mutate upstream ParseOutput
114
114
  const allFetchCalls = [...parseFetchCalls];
115
115
  const routeRegistry = new Map();
@@ -226,11 +226,14 @@ export const routesPhase = {
226
226
  if (!route.routePath)
227
227
  continue;
228
228
  const routeUrl = normalizeExtractedRoutePath(route.routePath, route.prefix);
229
- addRoute(routeUrl, {
230
- filePath: route.filePath,
231
- source: 'framework-route',
232
- method: normalizeRouteMethod(route.httpMethod),
233
- });
229
+ if (!selectedRoutes || selectedRoutes.has(route)) {
230
+ addRoute(routeUrl, {
231
+ filePath: route.filePath,
232
+ source: 'framework-route',
233
+ method: normalizeRouteMethod(route.httpMethod),
234
+ });
235
+ }
236
+ // Losing declarations may still provide distinct named aliases.
234
237
  if (route.routeName && !namedRouteRegistry.has(route.routeName)) {
235
238
  namedRouteRegistry.set(route.routeName, routeUrl);
236
239
  }
@@ -240,6 +243,8 @@ export const routesPhase = {
240
243
  // idiom, which no single file can reconcile. Framework routes are untouched;
241
244
  // their verb-less form is a declaration, not a weaker observation.
242
245
  for (const dr of reconcileDispatchGuardRoutes(allDecoratorRoutes)) {
246
+ if (selectedRoutes && !selectedRoutes.has(dr))
247
+ continue;
243
248
  const url = normalizeExtractedRoutePath(dr.routePath, dr.prefix ?? null);
244
249
  const method = normalizeRouteMethod(dr.httpMethod);
245
250
  const routeKey = routeNodeKey(method, url);
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Shared route-path normalization.
2
+ * Shared route-path normalization, route identity, and test-file classification.
3
3
  *
4
4
  * Extracted from the routes phase so both the routes phase (which creates the
5
5
  * `Route` graph node, keyed by `(method, url)` via `routeNodeKey` — #2289) and
6
6
  * the parse phase (which resolves each route's handler symbol and needs the
7
7
  * SAME key to associate the resolved id back to the route) can compute an
8
- * identical route identity without a phase-to-phase import cycle. Pure string
9
- * logic, no dependencies.
8
+ * identical route identity without a phase-to-phase import cycle. Test-route
9
+ * classification reuses the shared test-file path classifier.
10
10
  */
11
11
  /**
12
12
  * Join a route's path with its (optional) prefix into a normalized,
@@ -37,3 +37,5 @@ export declare function normalizeRouteMethod(raw: string | null | undefined): st
37
37
  * identically.
38
38
  */
39
39
  export declare function routeNodeKey(method: string | undefined, url: string): string;
40
+ /** Keep test registrations available, but let production files win duplicate route identities. */
41
+ export declare function isTestRouteFile(filePath: string): boolean;
@@ -1,12 +1,13 @@
1
+ import { isTestFilePath } from '../utils/test-file-path.js';
1
2
  /**
2
- * Shared route-path normalization.
3
+ * Shared route-path normalization, route identity, and test-file classification.
3
4
  *
4
5
  * Extracted from the routes phase so both the routes phase (which creates the
5
6
  * `Route` graph node, keyed by `(method, url)` via `routeNodeKey` — #2289) and
6
7
  * the parse phase (which resolves each route's handler symbol and needs the
7
8
  * SAME key to associate the resolved id back to the route) can compute an
8
- * identical route identity without a phase-to-phase import cycle. Pure string
9
- * logic, no dependencies.
9
+ * identical route identity without a phase-to-phase import cycle. Test-route
10
+ * classification reuses the shared test-file path classifier.
10
11
  */
11
12
  /**
12
13
  * Join a route's path with its (optional) prefix into a normalized,
@@ -64,3 +65,8 @@ export function normalizeRouteMethod(raw) {
64
65
  export function routeNodeKey(method, url) {
65
66
  return method && method !== '*' ? `${method} ${url}` : url;
66
67
  }
68
+ /** Keep test registrations available, but let production files win duplicate route identities. */
69
+ export function isTestRouteFile(filePath) {
70
+ const normalized = filePath.replace(/\\/g, '/');
71
+ return isTestFilePath(normalized) || /(^|\/)e2e(\/|$)/i.test(normalized);
72
+ }
@@ -71,7 +71,7 @@ catch { }
71
71
  import { getLanguageFromFilename } from '../../../_shared/index.js';
72
72
  import { buildDefinitionPreScan, FUNCTION_NODE_TYPES, findAncestorBeforeBoundary, findSplitBodyCallableAncestor, SPLIT_SIGNATURE_NODE_TYPES, getDefinitionNodeFromCaptures, findEnclosingClassInfo, findObjectLiteralBindingInfo, isArrayContainedObjectLiteralMember, findReturnShapeOwnerInfo, isReturnShapeProperty, findMemberAssignmentOwnerInfo, isCjsDefaultExportAssignment, getLabelFromCaptures, genericFuncName, inferFunctionLabel, isSuppressedConcreteTypedefDuplicate, isValueDefinitionLabel, isQualifiableScopeLabel, MEMBER_OWNER_NODE_TYPES, qualifyByEnclosingModScope, qualifyRustImplTargetByModScope, CLASS_CONTAINER_TYPES, PARAMETER_LIST_NODE_TYPES, LOCAL_SCOPE_BODY_NODE_TYPES, } from '../utils/ast-helpers.js';
73
73
  import { isPositionQualifiedLocalLabel } from '../utils/callable-labels.js';
74
- import { extractCallArgTypes } from '../utils/call-analysis.js';
74
+ import { countCallArguments, extractCallArgTypes, } from '../utils/call-analysis.js';
75
75
  import { buildTypeEnv } from '../type-env.js';
76
76
  import { detectFrameworkFromAST } from '../framework-detection.js';
77
77
  import { generateId } from '../../../lib/utils.js';
@@ -1404,6 +1404,11 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
1404
1404
  // HTTP client calls like axios.get('/api/users') that match the same pattern
1405
1405
  // as Express route registrations.
1406
1406
  const callNode = captureMap['express_route'];
1407
+ // route(path) returns a builder; verb registrations need a handler.
1408
+ // Count arguments without comments, which are also named AST children.
1409
+ const minimumArguments = method === 'route' ? 1 : 2;
1410
+ if ((countCallArguments(callNode) ?? 0) < minimumArguments)
1411
+ continue;
1407
1412
  const funcNode = callNode.childForFieldName?.('function') ?? callNode.children?.[0];
1408
1413
  // Walk through nested member_expressions and call_expressions to
1409
1414
  // reach the innermost receiver identifier. Handles chains like:
@@ -1439,16 +1444,47 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
1439
1444
  // This is an HTTP client call, not a route definition u2014 skip it
1440
1445
  continue;
1441
1446
  }
1442
- const httpMethod = method === 'all' || method === 'use' || method === 'route'
1443
- ? 'GET'
1444
- : method.toUpperCase();
1445
- result.decoratorRoutes.push({
1446
- filePath: file.path,
1447
- routePath,
1448
- httpMethod,
1449
- decoratorName: `express.${method}`,
1450
- lineNumber: captureMap['express_route'].startPosition.row + lineOffset,
1451
- });
1447
+ const registrations = [];
1448
+ if (method === 'route') {
1449
+ // A builder alone registers nothing. Follow only direct chained
1450
+ // verb calls, each of which must supply a non-comment handler arg.
1451
+ let builderNode = callNode;
1452
+ while (builderNode.parent?.type === 'member_expression') {
1453
+ const member = builderNode.parent;
1454
+ const registration = member.parent;
1455
+ const verb = member.childForFieldName('property')?.text;
1456
+ if (member.childForFieldName('object')?.id !== builderNode.id ||
1457
+ registration?.type !== 'call_expression' ||
1458
+ registration.childForFieldName('function')?.id !== member.id ||
1459
+ !verb ||
1460
+ !EXPRESS_ROUTE_METHODS.has(verb) ||
1461
+ verb === 'route' ||
1462
+ verb === 'use') {
1463
+ break;
1464
+ }
1465
+ if ((countCallArguments(registration) ?? 0) >= 1) {
1466
+ registrations.push({ method: verb, node: registration });
1467
+ }
1468
+ builderNode = registration;
1469
+ }
1470
+ }
1471
+ else {
1472
+ registrations.push({ method, node: callNode });
1473
+ }
1474
+ for (const registration of registrations) {
1475
+ const httpMethod = registration.method === 'all'
1476
+ ? '*'
1477
+ : registration.method === 'use'
1478
+ ? 'GET'
1479
+ : registration.method.toUpperCase();
1480
+ result.decoratorRoutes.push({
1481
+ filePath: file.path,
1482
+ routePath,
1483
+ httpMethod,
1484
+ decoratorName: `express.${registration.method}`,
1485
+ lineNumber: registration.node.startPosition.row + lineOffset,
1486
+ });
1487
+ }
1452
1488
  }
1453
1489
  continue;
1454
1490
  }
@@ -833,7 +833,14 @@ import { copyV8CacheIfPresent, tryLoadV8Cache, writeV8CacheFile } from './v8-sid
833
833
  // v131 (#3504): Python namespace imports retain explicit alias syntax. Warm
834
834
  // v130 ParsedFiles lack this fact and can bind a root-spelled alias to the
835
835
  // package root instead of the imported module.
836
- const SCHEMA_BUMP = 131;
836
+ // v132 (#3487, #3505): merge the parallel Express route capture changes.
837
+ // Require semantic handler arguments, retain route(path) builders, and preserve
838
+ // app.all as method-agnostic. Both branches used v131 for different captures,
839
+ // so invalidate either branch's cache before reusing the combined schema.
840
+ // v133 (#3505): route(path) builders emit only chained verb registrations
841
+ // with semantic handler arguments. Warm v132 caches can retain phantom GET
842
+ // routes for bare builders and lose the actual methods of chained handlers.
843
+ const SCHEMA_BUMP = 133;
837
844
  const GITNEXUS_PKG_VERSION = (() => {
838
845
  try {
839
846
  // package.json sits at gitnexus/package.json — two levels up from
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.13-rc.91",
3
+ "version": "1.6.13-rc.92",
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",