gitnexus 1.6.4-rc.12 → 1.6.4-rc.13

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.
@@ -58,6 +58,31 @@ const BUILT_INS = new Set([
58
58
  'sum',
59
59
  'abs',
60
60
  ]);
61
+ function pythonDescriptionExtractor(nodeLabel, _nodeName, captureMap) {
62
+ if (nodeLabel !== 'Function' && nodeLabel !== 'Method')
63
+ return undefined;
64
+ const functionNode = captureMap['definition.function'] ?? captureMap['definition.method'];
65
+ if (functionNode === undefined)
66
+ return undefined;
67
+ return extractPythonDocstring(functionNode);
68
+ }
69
+ function extractPythonDocstring(functionNode) {
70
+ const body = functionNode.childForFieldName('body');
71
+ const firstStatement = body?.namedChild(0);
72
+ if (firstStatement?.type !== 'expression_statement')
73
+ return undefined;
74
+ const literal = firstStatement.namedChild(0);
75
+ if (literal?.type !== 'string')
76
+ return undefined;
77
+ return normalizePythonStringLiteral(literal.text);
78
+ }
79
+ function normalizePythonStringLiteral(text) {
80
+ const match = text.match(/^[rRuUbBfF]*("""|'''|"|')([\s\S]*)\1$/);
81
+ const raw = match?.[2]?.trim();
82
+ if (!raw)
83
+ return undefined;
84
+ return raw.replace(/\s+/g, ' ');
85
+ }
61
86
  export const pythonProvider = defineLanguage({
62
87
  id: SupportedLanguages.Python,
63
88
  extensions: ['.py'],
@@ -74,6 +99,7 @@ export const pythonProvider = defineLanguage({
74
99
  variableExtractor: createVariableExtractor(pythonVariableConfig),
75
100
  classExtractor: createClassExtractor(pythonClassConfig),
76
101
  heritageExtractor: createHeritageExtractor(SupportedLanguages.Python),
102
+ descriptionExtractor: pythonDescriptionExtractor,
77
103
  builtInNames: BUILT_INS,
78
104
  labelOverride: pythonFunctionDefinitionLabel,
79
105
  // ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
@@ -84,12 +84,15 @@ export const processesPhase = {
84
84
  }
85
85
  list.push(url);
86
86
  }
87
- const toolsByFile = new Map();
87
+ const toolsByHandlerId = new Map();
88
+ const toolsWithoutHandlerByFile = new Map();
88
89
  for (const td of toolDefs) {
89
- let list = toolsByFile.get(td.filePath);
90
+ const key = td.handlerNodeId ?? td.filePath;
91
+ const targetMap = td.handlerNodeId ? toolsByHandlerId : toolsWithoutHandlerByFile;
92
+ let list = targetMap.get(key);
90
93
  if (!list) {
91
94
  list = [];
92
- toolsByFile.set(td.filePath, list);
95
+ targetMap.set(key, list);
93
96
  }
94
97
  list.push(td.name);
95
98
  }
@@ -118,7 +121,9 @@ export const processesPhase = {
118
121
  linked++;
119
122
  }
120
123
  }
121
- const toolNames = toolsByFile.get(entryFile);
124
+ const exactToolNames = toolsByHandlerId.get(proc.entryPointId);
125
+ const fallbackToolNames = toolsWithoutHandlerByFile.get(entryFile);
126
+ const toolNames = exactToolNames ?? fallbackToolNames;
122
127
  if (toolNames) {
123
128
  for (const toolName of toolNames) {
124
129
  const toolNodeId = generateId('Tool', toolName);
@@ -13,6 +13,7 @@ export interface ToolDef {
13
13
  name: string;
14
14
  filePath: string;
15
15
  description: string;
16
+ handlerNodeId?: string;
16
17
  }
17
18
  export interface ToolsOutput {
18
19
  toolDefs: ToolDef[];
@@ -23,7 +23,13 @@ export const toolsPhase = {
23
23
  if (seenToolNames.has(td.toolName))
24
24
  continue;
25
25
  seenToolNames.add(td.toolName);
26
- toolDefs.push({ name: td.toolName, filePath: td.filePath, description: td.description });
26
+ const handlerNodeId = td.handlerNodeId && ctx.graph.getNode(td.handlerNodeId) ? td.handlerNodeId : undefined;
27
+ toolDefs.push({
28
+ name: td.toolName,
29
+ filePath: td.filePath,
30
+ description: td.description,
31
+ ...(handlerNodeId !== undefined ? { handlerNodeId } : {}),
32
+ });
27
33
  }
28
34
  // TS tool definition arrays — require inputSchema nearby
29
35
  const toolCandidatePaths = allPaths.filter((p) => (p.endsWith('.ts') || p.endsWith('.js')) &&
@@ -60,10 +66,10 @@ export const toolsPhase = {
60
66
  label: 'Tool',
61
67
  properties: { name: td.name, filePath: td.filePath, description: td.description },
62
68
  });
63
- const handlerFileId = generateId('File', td.filePath);
69
+ const handlerId = td.handlerNodeId ?? generateId('File', td.filePath);
64
70
  ctx.graph.addRelationship({
65
- id: generateId('HANDLES_TOOL', `${handlerFileId}->${toolNodeId}`),
66
- sourceId: handlerFileId,
71
+ id: generateId('HANDLES_TOOL', `${handlerId}->${toolNodeId}`),
72
+ sourceId: handlerId,
67
73
  targetId: toolNodeId,
68
74
  type: 'HANDLES_TOOL',
69
75
  confidence: 1.0,
@@ -117,6 +117,7 @@ export interface ExtractedToolDef {
117
117
  toolName: string;
118
118
  description: string;
119
119
  lineNumber: number;
120
+ handlerNodeId?: string;
120
121
  }
121
122
  export interface ExtractedORMQuery {
122
123
  filePath: string;
@@ -1668,8 +1668,9 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
1668
1668
  result.toolDefs.push({
1669
1669
  filePath: file.path,
1670
1670
  toolName: nodeName,
1671
- description: dec.arg || '',
1671
+ description: (dec.arg || description || '').slice(0, 200),
1672
1672
  lineNumber: definitionNode.startPosition.row + lineOffset,
1673
+ handlerNodeId: nodeId,
1673
1674
  });
1674
1675
  }
1675
1676
  fileDecorators.delete(checkLine);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.4-rc.12",
3
+ "version": "1.6.4-rc.13",
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",