gitnexus 1.4.1 → 1.4.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.
Files changed (169) hide show
  1. package/README.md +215 -194
  2. package/dist/cli/ai-context.d.ts +2 -1
  3. package/dist/cli/ai-context.js +117 -90
  4. package/dist/cli/analyze.d.ts +2 -0
  5. package/dist/cli/analyze.js +57 -30
  6. package/dist/cli/augment.js +1 -1
  7. package/dist/cli/eval-server.d.ts +1 -1
  8. package/dist/cli/eval-server.js +1 -1
  9. package/dist/cli/index.js +18 -25
  10. package/dist/cli/lazy-action.d.ts +6 -0
  11. package/dist/cli/lazy-action.js +18 -0
  12. package/dist/cli/mcp.js +1 -1
  13. package/dist/cli/setup.js +42 -32
  14. package/dist/cli/skill-gen.d.ts +26 -0
  15. package/dist/cli/skill-gen.js +549 -0
  16. package/dist/cli/status.js +13 -4
  17. package/dist/cli/tool.d.ts +1 -1
  18. package/dist/cli/tool.js +2 -2
  19. package/dist/cli/wiki.js +2 -2
  20. package/dist/config/ignore-service.d.ts +25 -0
  21. package/dist/config/ignore-service.js +76 -0
  22. package/dist/config/supported-languages.d.ts +1 -0
  23. package/dist/config/supported-languages.js +1 -1
  24. package/dist/core/augmentation/engine.js +99 -72
  25. package/dist/core/embeddings/embedder.d.ts +1 -1
  26. package/dist/core/embeddings/embedder.js +1 -1
  27. package/dist/core/embeddings/embedding-pipeline.d.ts +3 -3
  28. package/dist/core/embeddings/embedding-pipeline.js +74 -47
  29. package/dist/core/embeddings/types.d.ts +1 -1
  30. package/dist/core/graph/types.d.ts +5 -2
  31. package/dist/core/ingestion/ast-cache.js +3 -2
  32. package/dist/core/ingestion/call-processor.d.ts +6 -7
  33. package/dist/core/ingestion/call-processor.js +560 -282
  34. package/dist/core/ingestion/call-routing.d.ts +53 -0
  35. package/dist/core/ingestion/call-routing.js +108 -0
  36. package/dist/core/ingestion/cluster-enricher.js +16 -16
  37. package/dist/core/ingestion/constants.d.ts +16 -0
  38. package/dist/core/ingestion/constants.js +16 -0
  39. package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
  40. package/dist/core/ingestion/entry-point-scoring.js +94 -24
  41. package/dist/core/ingestion/export-detection.d.ts +18 -0
  42. package/dist/core/ingestion/export-detection.js +231 -0
  43. package/dist/core/ingestion/filesystem-walker.js +4 -3
  44. package/dist/core/ingestion/framework-detection.d.ts +5 -1
  45. package/dist/core/ingestion/framework-detection.js +48 -8
  46. package/dist/core/ingestion/heritage-processor.d.ts +13 -5
  47. package/dist/core/ingestion/heritage-processor.js +109 -55
  48. package/dist/core/ingestion/import-processor.d.ts +16 -20
  49. package/dist/core/ingestion/import-processor.js +202 -696
  50. package/dist/core/ingestion/language-config.d.ts +46 -0
  51. package/dist/core/ingestion/language-config.js +167 -0
  52. package/dist/core/ingestion/mro-processor.d.ts +45 -0
  53. package/dist/core/ingestion/mro-processor.js +369 -0
  54. package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
  55. package/dist/core/ingestion/named-binding-extraction.js +363 -0
  56. package/dist/core/ingestion/parsing-processor.d.ts +3 -11
  57. package/dist/core/ingestion/parsing-processor.js +82 -181
  58. package/dist/core/ingestion/pipeline.d.ts +5 -1
  59. package/dist/core/ingestion/pipeline.js +192 -116
  60. package/dist/core/ingestion/process-processor.js +2 -1
  61. package/dist/core/ingestion/resolution-context.d.ts +53 -0
  62. package/dist/core/ingestion/resolution-context.js +132 -0
  63. package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
  64. package/dist/core/ingestion/resolvers/csharp.js +109 -0
  65. package/dist/core/ingestion/resolvers/go.d.ts +19 -0
  66. package/dist/core/ingestion/resolvers/go.js +42 -0
  67. package/dist/core/ingestion/resolvers/index.d.ts +18 -0
  68. package/dist/core/ingestion/resolvers/index.js +13 -0
  69. package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
  70. package/dist/core/ingestion/resolvers/jvm.js +87 -0
  71. package/dist/core/ingestion/resolvers/php.d.ts +15 -0
  72. package/dist/core/ingestion/resolvers/php.js +35 -0
  73. package/dist/core/ingestion/resolvers/python.d.ts +19 -0
  74. package/dist/core/ingestion/resolvers/python.js +52 -0
  75. package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
  76. package/dist/core/ingestion/resolvers/ruby.js +15 -0
  77. package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
  78. package/dist/core/ingestion/resolvers/rust.js +73 -0
  79. package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
  80. package/dist/core/ingestion/resolvers/standard.js +123 -0
  81. package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
  82. package/dist/core/ingestion/resolvers/utils.js +122 -0
  83. package/dist/core/ingestion/symbol-table.d.ts +15 -1
  84. package/dist/core/ingestion/symbol-table.js +20 -12
  85. package/dist/core/ingestion/tree-sitter-queries.d.ts +12 -11
  86. package/dist/core/ingestion/tree-sitter-queries.js +642 -485
  87. package/dist/core/ingestion/type-env.d.ts +49 -0
  88. package/dist/core/ingestion/type-env.js +559 -0
  89. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
  90. package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
  91. package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
  92. package/dist/core/ingestion/type-extractors/csharp.js +369 -0
  93. package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
  94. package/dist/core/ingestion/type-extractors/go.js +436 -0
  95. package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
  96. package/dist/core/ingestion/type-extractors/index.js +31 -0
  97. package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
  98. package/dist/core/ingestion/type-extractors/jvm.js +654 -0
  99. package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
  100. package/dist/core/ingestion/type-extractors/php.js +411 -0
  101. package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
  102. package/dist/core/ingestion/type-extractors/python.js +392 -0
  103. package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
  104. package/dist/core/ingestion/type-extractors/ruby.js +389 -0
  105. package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
  106. package/dist/core/ingestion/type-extractors/rust.js +436 -0
  107. package/dist/core/ingestion/type-extractors/shared.d.ts +132 -0
  108. package/dist/core/ingestion/type-extractors/shared.js +571 -0
  109. package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
  110. package/dist/core/ingestion/type-extractors/swift.js +137 -0
  111. package/dist/core/ingestion/type-extractors/types.d.ts +95 -0
  112. package/dist/core/ingestion/type-extractors/types.js +1 -0
  113. package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
  114. package/dist/core/ingestion/type-extractors/typescript.js +480 -0
  115. package/dist/core/ingestion/utils.d.ts +98 -0
  116. package/dist/core/ingestion/utils.js +1064 -9
  117. package/dist/core/ingestion/workers/parse-worker.d.ts +38 -4
  118. package/dist/core/ingestion/workers/parse-worker.js +248 -359
  119. package/dist/core/ingestion/workers/worker-pool.js +8 -0
  120. package/dist/core/{kuzu → lbug}/csv-generator.d.ts +1 -1
  121. package/dist/core/{kuzu → lbug}/csv-generator.js +20 -4
  122. package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +19 -19
  123. package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +82 -82
  124. package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
  125. package/dist/core/{kuzu → lbug}/schema.js +304 -289
  126. package/dist/core/search/bm25-index.d.ts +4 -4
  127. package/dist/core/search/bm25-index.js +17 -16
  128. package/dist/core/search/hybrid-search.d.ts +2 -2
  129. package/dist/core/search/hybrid-search.js +9 -9
  130. package/dist/core/tree-sitter/parser-loader.js +9 -2
  131. package/dist/core/wiki/generator.d.ts +4 -52
  132. package/dist/core/wiki/generator.js +53 -552
  133. package/dist/core/wiki/graph-queries.d.ts +4 -46
  134. package/dist/core/wiki/graph-queries.js +103 -282
  135. package/dist/core/wiki/html-viewer.js +192 -192
  136. package/dist/core/wiki/llm-client.js +11 -73
  137. package/dist/core/wiki/prompts.d.ts +8 -52
  138. package/dist/core/wiki/prompts.js +86 -200
  139. package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
  140. package/dist/mcp/compatible-stdio-transport.js +200 -0
  141. package/dist/mcp/core/{kuzu-adapter.d.ts → lbug-adapter.d.ts} +7 -9
  142. package/dist/mcp/core/{kuzu-adapter.js → lbug-adapter.js} +77 -79
  143. package/dist/mcp/local/local-backend.d.ts +6 -6
  144. package/dist/mcp/local/local-backend.js +153 -146
  145. package/dist/mcp/resources.js +42 -42
  146. package/dist/mcp/server.js +18 -19
  147. package/dist/mcp/tools.js +103 -104
  148. package/dist/server/api.js +12 -12
  149. package/dist/server/mcp-http.d.ts +1 -1
  150. package/dist/server/mcp-http.js +1 -1
  151. package/dist/storage/repo-manager.d.ts +20 -2
  152. package/dist/storage/repo-manager.js +55 -1
  153. package/dist/types/pipeline.d.ts +1 -1
  154. package/hooks/claude/gitnexus-hook.cjs +238 -155
  155. package/hooks/claude/pre-tool-use.sh +79 -79
  156. package/hooks/claude/session-start.sh +42 -42
  157. package/package.json +98 -96
  158. package/scripts/patch-tree-sitter-swift.cjs +74 -74
  159. package/skills/gitnexus-cli.md +82 -82
  160. package/skills/gitnexus-debugging.md +89 -89
  161. package/skills/gitnexus-exploring.md +78 -78
  162. package/skills/gitnexus-guide.md +64 -64
  163. package/skills/gitnexus-impact-analysis.md +97 -97
  164. package/skills/gitnexus-pr-review.md +163 -163
  165. package/skills/gitnexus-refactoring.md +121 -121
  166. package/vendor/leiden/index.cjs +355 -355
  167. package/vendor/leiden/utils.cjs +392 -392
  168. package/dist/core/wiki/diagrams.d.ts +0 -27
  169. package/dist/core/wiki/diagrams.js +0 -163
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared Ruby call routing logic.
3
+ *
4
+ * Ruby expresses imports, heritage (mixins), and property definitions as
5
+ * method calls rather than syntax-level constructs. This module provides a
6
+ * routing function used by the CLI call-processor, CLI parse-worker, and
7
+ * the web call-processor so that the classification logic lives in one place.
8
+ *
9
+ * NOTE: This file is intentionally duplicated in gitnexus-web/ because the
10
+ * two packages have separate build targets (Node native vs WASM/browser).
11
+ * Keep both copies in sync until a shared package is introduced.
12
+ */
13
+ import { SupportedLanguages } from '../../config/supported-languages.js';
14
+ /** null = this call was not routed; fall through to default call handling */
15
+ export type CallRoutingResult = RubyCallRouting | null;
16
+ export type CallRouter = (calledName: string, callNode: any) => CallRoutingResult;
17
+ /** Per-language call routing. noRouting = no special routing (normal call processing) */
18
+ export declare const callRouters: Record<SupportedLanguages, CallRouter>;
19
+ export type RubyCallRouting = {
20
+ kind: 'import';
21
+ importPath: string;
22
+ isRelative: boolean;
23
+ } | {
24
+ kind: 'heritage';
25
+ items: RubyHeritageItem[];
26
+ } | {
27
+ kind: 'properties';
28
+ items: RubyPropertyItem[];
29
+ } | {
30
+ kind: 'call';
31
+ } | {
32
+ kind: 'skip';
33
+ };
34
+ export interface RubyHeritageItem {
35
+ enclosingClass: string;
36
+ mixinName: string;
37
+ heritageKind: 'include' | 'extend' | 'prepend';
38
+ }
39
+ export type RubyAccessorType = 'attr_accessor' | 'attr_reader' | 'attr_writer';
40
+ export interface RubyPropertyItem {
41
+ propName: string;
42
+ accessorType: RubyAccessorType;
43
+ startLine: number;
44
+ endLine: number;
45
+ }
46
+ /**
47
+ * Classify a Ruby call node and extract its semantic payload.
48
+ *
49
+ * @param calledName - The method name (e.g. 'require', 'include', 'attr_accessor')
50
+ * @param callNode - The tree-sitter `call` AST node
51
+ * @returns A discriminated union describing the call's semantic role
52
+ */
53
+ export declare function routeRubyCall(calledName: string, callNode: any): RubyCallRouting;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Shared Ruby call routing logic.
3
+ *
4
+ * Ruby expresses imports, heritage (mixins), and property definitions as
5
+ * method calls rather than syntax-level constructs. This module provides a
6
+ * routing function used by the CLI call-processor, CLI parse-worker, and
7
+ * the web call-processor so that the classification logic lives in one place.
8
+ *
9
+ * NOTE: This file is intentionally duplicated in gitnexus-web/ because the
10
+ * two packages have separate build targets (Node native vs WASM/browser).
11
+ * Keep both copies in sync until a shared package is introduced.
12
+ */
13
+ import { SupportedLanguages } from '../../config/supported-languages.js';
14
+ /** No-op router: returns null for every call (passthrough to normal processing) */
15
+ const noRouting = () => null;
16
+ /** Per-language call routing. noRouting = no special routing (normal call processing) */
17
+ export const callRouters = {
18
+ [SupportedLanguages.JavaScript]: noRouting,
19
+ [SupportedLanguages.TypeScript]: noRouting,
20
+ [SupportedLanguages.Python]: noRouting,
21
+ [SupportedLanguages.Java]: noRouting,
22
+ [SupportedLanguages.Kotlin]: noRouting,
23
+ [SupportedLanguages.Go]: noRouting,
24
+ [SupportedLanguages.Rust]: noRouting,
25
+ [SupportedLanguages.CSharp]: noRouting,
26
+ [SupportedLanguages.PHP]: noRouting,
27
+ [SupportedLanguages.Swift]: noRouting,
28
+ [SupportedLanguages.CPlusPlus]: noRouting,
29
+ [SupportedLanguages.C]: noRouting,
30
+ [SupportedLanguages.Ruby]: routeRubyCall,
31
+ };
32
+ // ── Pre-allocated singletons for common return values ────────────────────────
33
+ const CALL_RESULT = { kind: 'call' };
34
+ const SKIP_RESULT = { kind: 'skip' };
35
+ /** Max depth for parent-walking loops to prevent pathological AST traversals */
36
+ const MAX_PARENT_DEPTH = 50;
37
+ // ── Routing function ────────────────────────────────────────────────────────
38
+ /**
39
+ * Classify a Ruby call node and extract its semantic payload.
40
+ *
41
+ * @param calledName - The method name (e.g. 'require', 'include', 'attr_accessor')
42
+ * @param callNode - The tree-sitter `call` AST node
43
+ * @returns A discriminated union describing the call's semantic role
44
+ */
45
+ export function routeRubyCall(calledName, callNode) {
46
+ // ── require / require_relative → import ─────────────────────────────────
47
+ if (calledName === 'require' || calledName === 'require_relative') {
48
+ const argList = callNode.childForFieldName?.('arguments');
49
+ const stringNode = argList?.children?.find((c) => c.type === 'string');
50
+ const contentNode = stringNode?.children?.find((c) => c.type === 'string_content');
51
+ if (!contentNode)
52
+ return SKIP_RESULT;
53
+ let importPath = contentNode.text;
54
+ // Validate: reject null bytes, control chars, excessively long paths
55
+ if (!importPath || importPath.length > 1024 || /[\x00-\x1f]/.test(importPath)) {
56
+ return SKIP_RESULT;
57
+ }
58
+ const isRelative = calledName === 'require_relative';
59
+ if (isRelative && !importPath.startsWith('.')) {
60
+ importPath = './' + importPath;
61
+ }
62
+ return { kind: 'import', importPath, isRelative };
63
+ }
64
+ // ── include / extend / prepend → heritage (mixin) ──────────────────────
65
+ if (calledName === 'include' || calledName === 'extend' || calledName === 'prepend') {
66
+ let enclosingClass = null;
67
+ let current = callNode.parent;
68
+ let depth = 0;
69
+ while (current && ++depth <= MAX_PARENT_DEPTH) {
70
+ if (current.type === 'class' || current.type === 'module') {
71
+ const nameNode = current.childForFieldName?.('name');
72
+ if (nameNode) {
73
+ enclosingClass = nameNode.text;
74
+ break;
75
+ }
76
+ }
77
+ current = current.parent;
78
+ }
79
+ if (!enclosingClass)
80
+ return SKIP_RESULT;
81
+ const items = [];
82
+ const argList = callNode.childForFieldName?.('arguments');
83
+ for (const arg of (argList?.children ?? [])) {
84
+ if (arg.type === 'constant' || arg.type === 'scope_resolution') {
85
+ items.push({ enclosingClass, mixinName: arg.text, heritageKind: calledName });
86
+ }
87
+ }
88
+ return items.length > 0 ? { kind: 'heritage', items } : SKIP_RESULT;
89
+ }
90
+ // ── attr_accessor / attr_reader / attr_writer → property definitions ───
91
+ if (calledName === 'attr_accessor' || calledName === 'attr_reader' || calledName === 'attr_writer') {
92
+ const items = [];
93
+ const argList = callNode.childForFieldName?.('arguments');
94
+ for (const arg of (argList?.children ?? [])) {
95
+ if (arg.type === 'simple_symbol') {
96
+ items.push({
97
+ propName: arg.text.startsWith(':') ? arg.text.slice(1) : arg.text,
98
+ accessorType: calledName,
99
+ startLine: arg.startPosition.row,
100
+ endLine: arg.endPosition.row,
101
+ });
102
+ }
103
+ }
104
+ return items.length > 0 ? { kind: 'properties', items } : SKIP_RESULT;
105
+ }
106
+ // ── Everything else → regular call ─────────────────────────────────────
107
+ return CALL_RESULT;
108
+ }
@@ -13,12 +13,12 @@ const buildEnrichmentPrompt = (members, heuristicLabel) => {
13
13
  const memberList = limitedMembers
14
14
  .map(m => `${m.name} (${m.type})`)
15
15
  .join(', ');
16
- return `Analyze this code cluster and provide a semantic name and short description.
17
-
18
- Heuristic: "${heuristicLabel}"
19
- Members: ${memberList}${members.length > 20 ? ` (+${members.length - 20} more)` : ''}
20
-
21
- Reply with JSON only:
16
+ return `Analyze this code cluster and provide a semantic name and short description.
17
+
18
+ Heuristic: "${heuristicLabel}"
19
+ Members: ${memberList}${members.length > 20 ? ` (+${members.length - 20} more)` : ''}
20
+
21
+ Reply with JSON only:
22
22
  {"name": "2-4 word semantic name", "description": "One sentence describing purpose"}`;
23
23
  };
24
24
  // ============================================================================
@@ -115,18 +115,18 @@ export const enrichClustersBatch = async (communities, memberMap, llmClient, bat
115
115
  const memberList = limitedMembers
116
116
  .map(m => `${m.name} (${m.type})`)
117
117
  .join(', ');
118
- return `Cluster ${idx + 1} (id: ${community.id}):
119
- Heuristic: "${community.heuristicLabel}"
118
+ return `Cluster ${idx + 1} (id: ${community.id}):
119
+ Heuristic: "${community.heuristicLabel}"
120
120
  Members: ${memberList}`;
121
121
  }).join('\n\n');
122
- const prompt = `Analyze these code clusters and generate semantic names, keywords, and descriptions.
123
-
124
- ${batchPrompt}
125
-
126
- Output JSON array:
127
- [
128
- {"id": "comm_X", "name": "...", "keywords": [...], "description": "..."},
129
- ...
122
+ const prompt = `Analyze these code clusters and generate semantic names, keywords, and descriptions.
123
+
124
+ ${batchPrompt}
125
+
126
+ Output JSON array:
127
+ [
128
+ {"id": "comm_X", "name": "...", "keywords": [...], "description": "..."},
129
+ ...
130
130
  ]`;
131
131
  try {
132
132
  const response = await llmClient.generate(prompt);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Default minimum buffer size for tree-sitter parsing (512 KB).
3
+ * tree-sitter requires bufferSize >= file size in bytes.
4
+ */
5
+ export declare const TREE_SITTER_BUFFER_SIZE: number;
6
+ /**
7
+ * Maximum buffer size cap (32 MB) to prevent OOM on huge files.
8
+ * Also used as the file-size skip threshold — files larger than this are not parsed.
9
+ */
10
+ export declare const TREE_SITTER_MAX_BUFFER: number;
11
+ /**
12
+ * Compute adaptive buffer size for tree-sitter parsing.
13
+ * Uses 2× file size, clamped between 512 KB and 32 MB.
14
+ * Previous 256 KB fixed limit silently skipped files > ~200 KB (e.g., imgui.h at 411 KB).
15
+ */
16
+ export declare const getTreeSitterBufferSize: (contentLength: number) => number;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Default minimum buffer size for tree-sitter parsing (512 KB).
3
+ * tree-sitter requires bufferSize >= file size in bytes.
4
+ */
5
+ export const TREE_SITTER_BUFFER_SIZE = 512 * 1024;
6
+ /**
7
+ * Maximum buffer size cap (32 MB) to prevent OOM on huge files.
8
+ * Also used as the file-size skip threshold — files larger than this are not parsed.
9
+ */
10
+ export const TREE_SITTER_MAX_BUFFER = 32 * 1024 * 1024;
11
+ /**
12
+ * Compute adaptive buffer size for tree-sitter parsing.
13
+ * Uses 2× file size, clamped between 512 KB and 32 MB.
14
+ * Previous 256 KB fixed limit silently skipped files > ~200 KB (e.g., imgui.h at 411 KB).
15
+ */
16
+ export const getTreeSitterBufferSize = (contentLength) => Math.min(Math.max(contentLength * 2, TREE_SITTER_BUFFER_SIZE), TREE_SITTER_MAX_BUFFER);
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * This module is language-agnostic - language-specific patterns are defined per language.
11
11
  */
12
+ import { SupportedLanguages } from '../../config/supported-languages.js';
12
13
  export interface EntryPointScoreResult {
13
14
  score: number;
14
15
  reasons: string[];
@@ -26,7 +27,7 @@ export interface EntryPointScoreResult {
26
27
  * @param calleeCount - Number of functions this function calls
27
28
  * @returns Score and array of reasons explaining the score
28
29
  */
29
- export declare function calculateEntryPointScore(name: string, language: string, isExported: boolean, callerCount: number, calleeCount: number, filePath?: string): EntryPointScoreResult;
30
+ export declare function calculateEntryPointScore(name: string, language: SupportedLanguages, isExported: boolean, callerCount: number, calleeCount: number, filePath?: string): EntryPointScoreResult;
30
31
  /**
31
32
  * Check if a file path is a test file (should be excluded from entry points)
32
33
  * Covers common test file patterns across all supported languages
@@ -10,8 +10,9 @@
10
10
  * This module is language-agnostic - language-specific patterns are defined per language.
11
11
  */
12
12
  import { detectFrameworkFromPath } from './framework-detection.js';
13
+ import { SupportedLanguages } from '../../config/supported-languages.js';
13
14
  // ============================================================================
14
- // NAME PATTERNS - All 9 supported languages
15
+ // NAME PATTERNS - All 11 supported languages
15
16
  // ============================================================================
16
17
  /**
17
18
  * Common entry point naming patterns by language
@@ -34,65 +35,112 @@ const ENTRY_POINT_PATTERNS = {
34
35
  /^emit[A-Z]/, // emitEvent
35
36
  ],
36
37
  // JavaScript/TypeScript
37
- 'javascript': [
38
+ [SupportedLanguages.JavaScript]: [
38
39
  /^use[A-Z]/, // React hooks (useEffect, etc.)
39
40
  ],
40
- 'typescript': [
41
+ [SupportedLanguages.TypeScript]: [
41
42
  /^use[A-Z]/, // React hooks
42
43
  ],
43
44
  // Python
44
- 'python': [
45
+ [SupportedLanguages.Python]: [
45
46
  /^app$/, // Flask/FastAPI app
46
47
  /^(get|post|put|delete|patch)_/i, // REST conventions
47
48
  /^api_/, // API functions
48
49
  /^view_/, // Django views
49
50
  ],
50
51
  // Java
51
- 'java': [
52
+ [SupportedLanguages.Java]: [
52
53
  /^do[A-Z]/, // doGet, doPost (Servlets)
53
54
  /^create[A-Z]/, // Factory patterns
54
55
  /^build[A-Z]/, // Builder patterns
55
56
  /Service$/, // UserService
56
57
  ],
57
58
  // C#
58
- 'csharp': [
59
- /^(Get|Post|Put|Delete)/, // ASP.NET conventions
59
+ [SupportedLanguages.CSharp]: [
60
+ /^(Get|Post|Put|Delete|Patch)/, // ASP.NET action methods
60
61
  /Action$/, // MVC actions
61
- /^On[A-Z]/, // Event handlers
62
+ /^On[A-Z]/, // Event handlers / Blazor lifecycle
62
63
  /Async$/, // Async entry points
64
+ /^Configure$/, // Startup.Configure
65
+ /^ConfigureServices$/, // Startup.ConfigureServices
66
+ /^Handle$/, // MediatR / generic handler
67
+ /^Execute$/, // Command pattern
68
+ /^Invoke$/, // Middleware Invoke
69
+ /^Map[A-Z]/, // Minimal API MapGet, MapPost
70
+ /Service$/, // Service classes
71
+ /^Seed/, // Database seeding
63
72
  ],
64
73
  // Go
65
- 'go': [
74
+ [SupportedLanguages.Go]: [
66
75
  /Handler$/, // http.Handler pattern
67
76
  /^Serve/, // ServeHTTP
68
77
  /^New[A-Z]/, // Constructor pattern (returns new instance)
69
78
  /^Make[A-Z]/, // Make functions
70
79
  ],
71
80
  // Rust
72
- 'rust': [
81
+ [SupportedLanguages.Rust]: [
73
82
  /^(get|post|put|delete)_handler$/i,
74
83
  /^handle_/, // handle_request
75
84
  /^new$/, // Constructor pattern
76
85
  /^run$/, // run entry point
77
86
  /^spawn/, // Async spawn
78
87
  ],
79
- // C - explicit main() boost (critical for C programs)
80
- 'c': [
88
+ // C - explicit main() boost plus common C entry point conventions
89
+ [SupportedLanguages.C]: [
81
90
  /^main$/, // THE entry point
82
- /^init_/, // Initialization functions
83
- /^start_/, // Start functions
84
- /^run_/, // Run functions
91
+ /^init_/, // init_server, init_client
92
+ /_init$/, // module_init, server_init
93
+ /^start_/, // start_server
94
+ /_start$/, // thread_start
95
+ /^run_/, // run_loop
96
+ /_run$/, // event_run
97
+ /^stop_/, // stop_server
98
+ /_stop$/, // service_stop
99
+ /^open_/, // open_connection
100
+ /_open$/, // file_open
101
+ /^close_/, // close_connection
102
+ /_close$/, // socket_close
103
+ /^create_/, // create_session
104
+ /_create$/, // object_create
105
+ /^destroy_/, // destroy_session
106
+ /_destroy$/, // object_destroy
107
+ /^handle_/, // handle_request
108
+ /_handler$/, // signal_handler
109
+ /_callback$/, // event_callback
110
+ /^cmd_/, // tmux: cmd_new_window, cmd_attach_session
111
+ /^server_/, // server_start, server_loop
112
+ /^client_/, // client_connect
113
+ /^session_/, // session_create
114
+ /^window_/, // window_resize (tmux)
115
+ /^key_/, // key_press
116
+ /^input_/, // input_parse
117
+ /^output_/, // output_write
118
+ /^notify_/, // notify_client
119
+ /^control_/, // control_start
85
120
  ],
86
- // C++ - same as C plus class patterns
87
- 'cpp': [
121
+ // C++ - same as C plus OOP/template patterns
122
+ [SupportedLanguages.CPlusPlus]: [
88
123
  /^main$/, // THE entry point
89
124
  /^init_/,
125
+ /_init$/,
90
126
  /^Create[A-Z]/, // Factory patterns
127
+ /^create_/,
91
128
  /^Run$/, // Run methods
129
+ /^run$/,
92
130
  /^Start$/, // Start methods
131
+ /^start$/,
132
+ /^handle_/,
133
+ /_handler$/,
134
+ /_callback$/,
135
+ /^OnEvent/, // Event callbacks
136
+ /^on_/,
137
+ /::Run$/, // Class::Run
138
+ /::Start$/, // Class::Start
139
+ /::Init$/, // Class::Init
140
+ /::Execute$/, // Class::Execute
93
141
  ],
94
142
  // Swift / iOS
95
- 'swift': [
143
+ [SupportedLanguages.Swift]: [
96
144
  /^viewDidLoad$/, // UIKit lifecycle
97
145
  /^viewWillAppear$/, // UIKit lifecycle
98
146
  /^viewDidAppear$/, // UIKit lifecycle
@@ -111,7 +159,7 @@ const ENTRY_POINT_PATTERNS = {
111
159
  /^makeBody$/, // SwiftUI ViewModifier
112
160
  ],
113
161
  // PHP / Laravel
114
- 'php': [
162
+ [SupportedLanguages.PHP]: [
115
163
  /Controller$/, // UserController (class name convention)
116
164
  /^handle$/, // Job::handle(), Listener::handle()
117
165
  /^execute$/, // Command::execute()
@@ -130,7 +178,21 @@ const ENTRY_POINT_PATTERNS = {
130
178
  /^save$/, // Repository::save()
131
179
  /^delete$/, // Repository::delete()
132
180
  ],
181
+ // Ruby
182
+ [SupportedLanguages.Ruby]: [
183
+ /^call$/, // Service objects (MyService.call)
184
+ /^perform$/, // Background jobs (Sidekiq, ActiveJob)
185
+ /^execute$/, // Command pattern
186
+ ],
133
187
  };
188
+ /** Pre-computed merged patterns (universal + language-specific) to avoid per-call array allocation. */
189
+ const MERGED_ENTRY_POINT_PATTERNS = {};
190
+ const UNIVERSAL_PATTERNS = ENTRY_POINT_PATTERNS['*'] || [];
191
+ for (const [lang, patterns] of Object.entries(ENTRY_POINT_PATTERNS)) {
192
+ if (lang === '*')
193
+ continue;
194
+ MERGED_ENTRY_POINT_PATTERNS[lang] = [...UNIVERSAL_PATTERNS, ...patterns];
195
+ }
134
196
  // ============================================================================
135
197
  // UTILITY PATTERNS - Functions that should be penalized
136
198
  // ============================================================================
@@ -196,9 +258,7 @@ export function calculateEntryPointScore(name, language, isExported, callerCount
196
258
  }
197
259
  else {
198
260
  // Check positive patterns
199
- const universalPatterns = ENTRY_POINT_PATTERNS['*'] || [];
200
- const langPatterns = ENTRY_POINT_PATTERNS[language] || [];
201
- const allPatterns = [...universalPatterns, ...langPatterns];
261
+ const allPatterns = MERGED_ENTRY_POINT_PATTERNS[language] || UNIVERSAL_PATTERNS;
202
262
  if (allPatterns.some(p => p.test(name))) {
203
263
  nameMultiplier = 1.5; // Bonus for matching entry point pattern
204
264
  reasons.push('entry-pattern');
@@ -253,13 +313,23 @@ export function isTestFile(filePath) {
253
313
  p.endsWith('test.swift') ||
254
314
  p.includes('uitests/') ||
255
315
  // C# test patterns
316
+ p.endsWith('tests.cs') ||
317
+ p.endsWith('test.cs') ||
256
318
  p.includes('.tests/') ||
257
- p.includes('tests.cs') ||
319
+ p.includes('.test/') ||
320
+ p.includes('.integrationtests/') ||
321
+ p.includes('.unittests/') ||
322
+ p.includes('/testproject/') ||
258
323
  // PHP/Laravel test patterns
259
324
  p.endsWith('test.php') ||
260
325
  p.endsWith('spec.php') ||
261
326
  p.includes('/tests/feature/') ||
262
- p.includes('/tests/unit/'));
327
+ p.includes('/tests/unit/') ||
328
+ // Ruby test patterns
329
+ p.endsWith('_spec.rb') ||
330
+ p.endsWith('_test.rb') ||
331
+ p.includes('/spec/') ||
332
+ p.includes('/test/fixtures/'));
263
333
  }
264
334
  /**
265
335
  * Check if a file path is likely a utility/helper file
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Export Detection
3
+ *
4
+ * Determines whether a symbol (function, class, etc.) is exported/public
5
+ * in its language. This is a pure function — safe for use in worker threads.
6
+ *
7
+ * Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
8
+ */
9
+ import { SyntaxNode } from './utils.js';
10
+ import { SupportedLanguages } from '../../config/supported-languages.js';
11
+ /**
12
+ * Check if a tree-sitter node is exported/public in its language.
13
+ * @param node - The tree-sitter AST node
14
+ * @param name - The symbol name
15
+ * @param language - The programming language
16
+ * @returns true if the symbol is exported/public
17
+ */
18
+ export declare const isNodeExported: (node: SyntaxNode, name: string, language: SupportedLanguages) => boolean;