@rigour-labs/core 5.0.1 → 5.1.0

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 (139) hide show
  1. package/README.md +9 -1
  2. package/dist/gates/agent-team.d.ts +0 -1
  3. package/dist/gates/agent-team.js +0 -1
  4. package/dist/gates/checkpoint.d.ts +0 -2
  5. package/dist/gates/checkpoint.js +0 -2
  6. package/dist/gates/context-window-artifacts.d.ts +6 -2
  7. package/dist/gates/context-window-artifacts.js +107 -31
  8. package/dist/gates/deep-analysis.d.ts +2 -0
  9. package/dist/gates/deep-analysis.js +41 -11
  10. package/dist/gates/dependency.d.ts +0 -2
  11. package/dist/gates/dependency.js +23 -5
  12. package/dist/gates/deprecated-apis.d.ts +0 -2
  13. package/dist/gates/deprecated-apis.js +33 -20
  14. package/dist/gates/duplication-drift/index.d.ts +61 -0
  15. package/dist/gates/duplication-drift/index.js +240 -0
  16. package/dist/gates/duplication-drift/similarity.d.ts +68 -0
  17. package/dist/gates/duplication-drift/similarity.js +177 -0
  18. package/dist/gates/duplication-drift/tokenizer.d.ts +55 -0
  19. package/dist/gates/duplication-drift/tokenizer.js +195 -0
  20. package/dist/gates/frontend-secret-exposure.d.ts +0 -3
  21. package/dist/gates/frontend-secret-exposure.js +1 -114
  22. package/dist/gates/frontend-secret-patterns.d.ts +33 -0
  23. package/dist/gates/frontend-secret-patterns.js +119 -0
  24. package/dist/gates/{hallucinated-imports.d.ts → hallucinated-imports/index.d.ts} +2 -29
  25. package/dist/gates/hallucinated-imports/index.js +174 -0
  26. package/dist/gates/hallucinated-imports/js-resolver.d.ts +45 -0
  27. package/dist/gates/hallucinated-imports/js-resolver.js +320 -0
  28. package/dist/gates/hallucinated-imports/manifest-discovery.d.ts +28 -0
  29. package/dist/gates/hallucinated-imports/manifest-discovery.js +114 -0
  30. package/dist/gates/hallucinated-imports/python-resolver.d.ts +24 -0
  31. package/dist/gates/hallucinated-imports/python-resolver.js +306 -0
  32. package/dist/gates/hallucinated-imports-lang.d.ts +2 -2
  33. package/dist/gates/hallucinated-imports-lang.js +269 -34
  34. package/dist/gates/hallucinated-imports.test.js +1 -2
  35. package/dist/gates/inconsistent-error-handling.d.ts +0 -5
  36. package/dist/gates/inconsistent-error-handling.js +15 -144
  37. package/dist/gates/language-adapters/csharp-adapter.d.ts +16 -0
  38. package/dist/gates/language-adapters/csharp-adapter.js +211 -0
  39. package/dist/gates/language-adapters/go-adapter.d.ts +26 -0
  40. package/dist/gates/language-adapters/go-adapter.js +195 -0
  41. package/dist/gates/language-adapters/index.d.ts +15 -0
  42. package/dist/gates/language-adapters/index.js +16 -0
  43. package/dist/gates/language-adapters/java-adapter.d.ts +16 -0
  44. package/dist/gates/language-adapters/java-adapter.js +237 -0
  45. package/dist/gates/language-adapters/js-adapter.d.ts +26 -0
  46. package/dist/gates/language-adapters/js-adapter.js +279 -0
  47. package/dist/gates/language-adapters/python-adapter.d.ts +25 -0
  48. package/dist/gates/language-adapters/python-adapter.js +183 -0
  49. package/dist/gates/language-adapters/registry.d.ts +26 -0
  50. package/dist/gates/language-adapters/registry.js +65 -0
  51. package/dist/gates/language-adapters/ruby-adapter.d.ts +25 -0
  52. package/dist/gates/language-adapters/ruby-adapter.js +217 -0
  53. package/dist/gates/language-adapters/rust-adapter.d.ts +27 -0
  54. package/dist/gates/language-adapters/rust-adapter.js +235 -0
  55. package/dist/gates/language-adapters/types.d.ts +60 -0
  56. package/dist/gates/language-adapters/types.js +22 -0
  57. package/dist/gates/logic-drift-extractors.d.ts +15 -0
  58. package/dist/gates/logic-drift-extractors.js +34 -0
  59. package/dist/gates/logic-drift.d.ts +0 -30
  60. package/dist/gates/logic-drift.js +39 -129
  61. package/dist/gates/phantom-apis.d.ts +0 -2
  62. package/dist/gates/phantom-apis.js +49 -20
  63. package/dist/gates/promise-safety.d.ts +0 -1
  64. package/dist/gates/promise-safety.js +14 -2
  65. package/dist/gates/runner.js +51 -22
  66. package/dist/gates/security-patterns-data.d.ts +14 -0
  67. package/dist/gates/security-patterns-data.js +235 -0
  68. package/dist/gates/security-patterns.d.ts +17 -3
  69. package/dist/gates/security-patterns.js +80 -211
  70. package/dist/gates/side-effect-analysis/categorizer.d.ts +32 -0
  71. package/dist/gates/side-effect-analysis/categorizer.js +83 -0
  72. package/dist/gates/{side-effect-analysis.d.ts → side-effect-analysis/index.d.ts} +3 -5
  73. package/dist/gates/{side-effect-analysis.js → side-effect-analysis/index.js} +33 -45
  74. package/dist/gates/side-effect-analysis/scope-tracker.d.ts +37 -0
  75. package/dist/gates/side-effect-analysis/scope-tracker.js +40 -0
  76. package/dist/gates/side-effect-helpers/index.d.ts +4 -0
  77. package/dist/gates/side-effect-helpers/index.js +4 -0
  78. package/dist/gates/side-effect-helpers/pattern-detection.d.ts +123 -0
  79. package/dist/gates/{side-effect-helpers.js → side-effect-helpers/pattern-detection.js} +22 -468
  80. package/dist/gates/side-effect-helpers/resource-tracking.d.ts +80 -0
  81. package/dist/gates/side-effect-helpers/resource-tracking.js +281 -0
  82. package/dist/gates/side-effect-helpers/scope-analysis.d.ts +21 -0
  83. package/dist/gates/side-effect-helpers/scope-analysis.js +146 -0
  84. package/dist/gates/side-effect-helpers/types.d.ts +38 -0
  85. package/dist/gates/side-effect-helpers/types.js +41 -0
  86. package/dist/gates/side-effect-rules.d.ts +0 -1
  87. package/dist/gates/side-effect-rules.js +0 -1
  88. package/dist/gates/style-drift-rules.d.ts +86 -0
  89. package/dist/gates/style-drift-rules.js +103 -0
  90. package/dist/gates/style-drift.d.ts +7 -16
  91. package/dist/gates/style-drift.js +101 -119
  92. package/dist/gates/test-quality-matchers.d.ts +53 -0
  93. package/dist/gates/test-quality-matchers.js +86 -0
  94. package/dist/gates/test-quality.d.ts +0 -3
  95. package/dist/gates/test-quality.js +47 -44
  96. package/dist/hooks/checker.d.ts +0 -1
  97. package/dist/hooks/checker.js +0 -2
  98. package/dist/hooks/dlp-templates.d.ts +0 -1
  99. package/dist/hooks/dlp-templates.js +0 -4
  100. package/dist/hooks/index.d.ts +0 -2
  101. package/dist/hooks/index.js +0 -2
  102. package/dist/hooks/input-validator.d.ts +0 -1
  103. package/dist/hooks/input-validator.js +0 -1
  104. package/dist/hooks/input-validator.test.js +0 -1
  105. package/dist/hooks/standalone-checker.d.ts +0 -1
  106. package/dist/hooks/standalone-checker.js +0 -1
  107. package/dist/hooks/standalone-dlp-checker.d.ts +0 -1
  108. package/dist/hooks/standalone-dlp-checker.js +0 -1
  109. package/dist/hooks/templates.d.ts +0 -1
  110. package/dist/hooks/templates.js +0 -1
  111. package/dist/hooks/types.d.ts +0 -1
  112. package/dist/hooks/types.js +0 -1
  113. package/dist/index.d.ts +1 -1
  114. package/dist/index.js +1 -1
  115. package/dist/services/adaptive-thresholds.d.ts +0 -2
  116. package/dist/services/adaptive-thresholds.js +0 -2
  117. package/dist/services/filesystem-cache.d.ts +0 -1
  118. package/dist/services/filesystem-cache.js +0 -1
  119. package/dist/services/score-history.d.ts +0 -1
  120. package/dist/services/score-history.js +0 -1
  121. package/dist/services/temporal-drift.d.ts +1 -2
  122. package/dist/services/temporal-drift.js +7 -8
  123. package/dist/storage/db.d.ts +23 -7
  124. package/dist/storage/db.js +116 -55
  125. package/dist/storage/findings.d.ts +4 -3
  126. package/dist/storage/findings.js +13 -20
  127. package/dist/storage/local-memory.d.ts +4 -4
  128. package/dist/storage/local-memory.js +20 -22
  129. package/dist/storage/patterns.d.ts +5 -5
  130. package/dist/storage/patterns.js +20 -26
  131. package/dist/storage/scans.d.ts +6 -6
  132. package/dist/storage/scans.js +12 -21
  133. package/dist/types/index.d.ts +1 -0
  134. package/dist/utils/scanner.js +1 -1
  135. package/package.json +7 -8
  136. package/dist/gates/duplication-drift.d.ts +0 -128
  137. package/dist/gates/duplication-drift.js +0 -585
  138. package/dist/gates/hallucinated-imports.js +0 -641
  139. package/dist/gates/side-effect-helpers.d.ts +0 -260
@@ -0,0 +1,211 @@
1
+ import { classifyCasing } from './types.js';
2
+ class CSharpAdapter {
3
+ id = 'csharp';
4
+ name = 'C#';
5
+ extensions = ['.cs'];
6
+ extractFunctions(source) {
7
+ const lines = source.split('\n');
8
+ const functions = [];
9
+ // Match: public/private/protected/internal static? async? ReturnType MethodName(
10
+ const methodRegex = /^\s*(public|private|protected|internal)?\s*(static)?\s*(async)?\s*(\w+)\s+(\w+)\s*\(/;
11
+ let i = 0;
12
+ while (i < lines.length) {
13
+ const match = lines[i].match(methodRegex);
14
+ if (match) {
15
+ const isAsync = !!match[3];
16
+ const returnType = match[4];
17
+ const methodName = match[5];
18
+ const startLine = i + 1;
19
+ // Find closing brace
20
+ let braceCount = 0;
21
+ let foundOpening = false;
22
+ let j = i;
23
+ let body = '';
24
+ while (j < lines.length) {
25
+ const line = lines[j];
26
+ for (let k = 0; k < line.length; k++) {
27
+ if (line[k] === '{') {
28
+ braceCount++;
29
+ foundOpening = true;
30
+ }
31
+ else if (line[k] === '}') {
32
+ braceCount--;
33
+ }
34
+ }
35
+ body += line + '\n';
36
+ if (foundOpening && braceCount === 0)
37
+ break;
38
+ j++;
39
+ }
40
+ functions.push({
41
+ name: methodName,
42
+ startLine,
43
+ endLine: j + 1,
44
+ body: body.trim(),
45
+ isAsync,
46
+ isExported: lines[i].includes('public'),
47
+ });
48
+ i = j + 1;
49
+ }
50
+ else {
51
+ i++;
52
+ }
53
+ }
54
+ return functions;
55
+ }
56
+ extractImports(source) {
57
+ const imports = [];
58
+ const lines = source.split('\n');
59
+ // Match: using Namespace; or using static Namespace;
60
+ const usingRegex = /^\s*using\s+(static\s+)?([^;]+);/;
61
+ lines.forEach((line, idx) => {
62
+ const match = line.match(usingRegex);
63
+ if (match) {
64
+ const module = match[2].trim();
65
+ imports.push({
66
+ module,
67
+ names: [],
68
+ line: idx + 1,
69
+ isDynamic: false,
70
+ });
71
+ }
72
+ });
73
+ return imports;
74
+ }
75
+ extractErrorHandlers(source) {
76
+ const handlers = [];
77
+ const lines = source.split('\n');
78
+ // Match: catch (ExceptionType e) {
79
+ const catchRegex = /catch\s*\(\s*(\w+)\s+\w+\s*\)\s*{/;
80
+ let i = 0;
81
+ while (i < lines.length) {
82
+ const match = lines[i].match(catchRegex);
83
+ if (match) {
84
+ const exceptionType = match[1];
85
+ const startLine = i + 1;
86
+ // Extract catch block
87
+ let braceCount = 0;
88
+ let foundOpening = false;
89
+ let j = i;
90
+ let body = '';
91
+ while (j < lines.length) {
92
+ const line = lines[j];
93
+ for (let k = 0; k < line.length; k++) {
94
+ if (line[k] === '{') {
95
+ braceCount++;
96
+ foundOpening = true;
97
+ }
98
+ else if (line[k] === '}') {
99
+ braceCount--;
100
+ }
101
+ }
102
+ body += line + '\n';
103
+ if (foundOpening && braceCount === 0)
104
+ break;
105
+ j++;
106
+ }
107
+ // Classify strategy
108
+ let strategy = 'swallow';
109
+ if (/\bthrow\s*;/.test(body)) {
110
+ strategy = 'rethrow';
111
+ }
112
+ else if (/\bthrow\s+new\s+/.test(body)) {
113
+ strategy = 'wrap';
114
+ }
115
+ else if (/Console\.(Write|WriteLine)/.test(body)) {
116
+ strategy = 'log';
117
+ }
118
+ handlers.push({
119
+ type: 'try-catch',
120
+ strategy,
121
+ startLine,
122
+ body: body.trim(),
123
+ });
124
+ i = j + 1;
125
+ }
126
+ else {
127
+ i++;
128
+ }
129
+ }
130
+ return handlers;
131
+ }
132
+ extractNamingPatterns(source) {
133
+ const patterns = [];
134
+ // Extract PascalCase methods
135
+ const methodRegex = /\b(public|private|protected|internal)?\s*(static)?\s*\w+\s+([A-Z]\w+)\s*\(/g;
136
+ let match;
137
+ while ((match = methodRegex.exec(source)) !== null) {
138
+ patterns.push({
139
+ name: match[3],
140
+ kind: 'method',
141
+ convention: classifyCasing(match[3]),
142
+ });
143
+ }
144
+ // Extract PascalCase class declarations
145
+ const classRegex = /\bclass\s+([A-Z]\w+)/g;
146
+ while ((match = classRegex.exec(source)) !== null) {
147
+ patterns.push({
148
+ name: match[1],
149
+ kind: 'class',
150
+ convention: classifyCasing(match[1]),
151
+ });
152
+ }
153
+ // Extract _camelCase private fields
154
+ const fieldRegex = /\b(_[a-z]\w+)\s*[=;]/g;
155
+ while ((match = fieldRegex.exec(source)) !== null) {
156
+ patterns.push({
157
+ name: match[1],
158
+ kind: 'variable',
159
+ convention: classifyCasing(match[1]),
160
+ });
161
+ }
162
+ // Extract SCREAMING_SNAKE constants
163
+ const constRegex = /\b(const\s+)?([A-Z][A-Z0-9_]*)\s*=/g;
164
+ while ((match = constRegex.exec(source)) !== null) {
165
+ const name = match[2];
166
+ if (/^[A-Z][A-Z0-9_]+$/.test(name)) {
167
+ patterns.push({
168
+ name,
169
+ kind: 'constant',
170
+ convention: classifyCasing(name),
171
+ });
172
+ }
173
+ }
174
+ return patterns;
175
+ }
176
+ stripComments(source) {
177
+ // Remove // comments
178
+ let result = source.replace(/\/\/.*$/gm, '');
179
+ // Remove /* */ comments (handles multiline)
180
+ result = result.replace(/\/\*[\s\S]*?\*\//g, '');
181
+ return result;
182
+ }
183
+ extractComparisonOps(source) {
184
+ const ops = new Set();
185
+ const opsRegex = /(>=|<=|==|!=|>|<)/g;
186
+ let match;
187
+ while ((match = opsRegex.exec(source)) !== null) {
188
+ ops.add(match[1]);
189
+ }
190
+ return Array.from(ops);
191
+ }
192
+ countBranches(source) {
193
+ const stripped = this.stripComments(source);
194
+ const ifMatches = stripped.match(/\bif\s*\(/g) || [];
195
+ const elseIfMatches = stripped.match(/\belse\s+if\s*\(/g) || [];
196
+ const elseMatches = stripped.match(/\belse\s*{/g) || [];
197
+ const switchMatches = stripped.match(/\bswitch\s*\(/g) || [];
198
+ const caseMatches = stripped.match(/\bcase\s+/g) || [];
199
+ return (ifMatches.length +
200
+ elseIfMatches.length +
201
+ elseMatches.length +
202
+ switchMatches.length +
203
+ caseMatches.length);
204
+ }
205
+ countReturns(source) {
206
+ const stripped = this.stripComments(source);
207
+ const returnMatches = stripped.match(/\breturn\b/g) || [];
208
+ return returnMatches.length;
209
+ }
210
+ }
211
+ export const csharpAdapter = new CSharpAdapter();
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Go Language Adapter
3
+ *
4
+ * Handles Go-specific code analysis:
5
+ * - Function extraction (func Name, func (r *Receiver) Name)
6
+ * - Import parsing (single and multiline blocks)
7
+ * - Error handling (if err != nil patterns)
8
+ * - Naming conventions (PascalCase exports, camelCase unexported)
9
+ */
10
+ import { LanguageAdapter, FunctionFact, ImportFact, ErrorHandlerFact, NamingPattern } from './types.js';
11
+ export declare class GoAdapter implements LanguageAdapter {
12
+ readonly id = "go";
13
+ readonly name = "Go";
14
+ readonly extensions: string[];
15
+ extractFunctions(source: string, filePath?: string): FunctionFact[];
16
+ extractImports(source: string): ImportFact[];
17
+ extractErrorHandlers(source: string): ErrorHandlerFact[];
18
+ extractNamingPatterns(source: string): NamingPattern[];
19
+ stripComments(source: string): string;
20
+ extractComparisonOps(source: string): string[];
21
+ countBranches(source: string): number;
22
+ countReturns(source: string): number;
23
+ private extractBraceBody;
24
+ private classifyGoErrorStrategy;
25
+ }
26
+ export declare const goAdapter: GoAdapter;
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Go Language Adapter
3
+ *
4
+ * Handles Go-specific code analysis:
5
+ * - Function extraction (func Name, func (r *Receiver) Name)
6
+ * - Import parsing (single and multiline blocks)
7
+ * - Error handling (if err != nil patterns)
8
+ * - Naming conventions (PascalCase exports, camelCase unexported)
9
+ */
10
+ import { classifyCasing } from './types.js';
11
+ export class GoAdapter {
12
+ id = 'go';
13
+ name = 'Go';
14
+ extensions = ['.go'];
15
+ extractFunctions(source, filePath) {
16
+ const functions = [];
17
+ const lines = source.split('\n');
18
+ // Match: func Name(...) or func (r *Receiver) Name(...)
19
+ const funcRegex = /^\s*func\s+(?:\([^)]+\)\s+)?(\w+)\s*\(/;
20
+ for (let i = 0; i < lines.length; i++) {
21
+ const match = lines[i].match(funcRegex);
22
+ if (!match)
23
+ continue;
24
+ const name = match[1];
25
+ const startLine = i + 1;
26
+ const body = this.extractBraceBody(lines, i);
27
+ const bodyStr = body.join('\n');
28
+ functions.push({
29
+ name,
30
+ startLine,
31
+ endLine: startLine + body.length,
32
+ body: bodyStr,
33
+ isAsync: false,
34
+ isExported: /^[A-Z]/.test(name),
35
+ });
36
+ }
37
+ return functions;
38
+ }
39
+ extractImports(source) {
40
+ const imports = [];
41
+ const lines = source.split('\n');
42
+ for (let i = 0; i < lines.length; i++) {
43
+ const line = lines[i].trim();
44
+ // Single import: import "pkg"
45
+ const singleMatch = line.match(/^\s*import\s+"([^"]+)"/);
46
+ if (singleMatch) {
47
+ imports.push({
48
+ module: singleMatch[1],
49
+ names: [],
50
+ line: i + 1,
51
+ isDynamic: false,
52
+ });
53
+ continue;
54
+ }
55
+ // Multiline import block: import ( "pkg1" "pkg2" )
56
+ if (line.startsWith('import') && line.includes('(')) {
57
+ let j = i;
58
+ while (j < lines.length && !lines[j].includes(')')) {
59
+ j++;
60
+ }
61
+ for (let k = i + 1; k < j; k++) {
62
+ const importLine = lines[k].trim();
63
+ if (importLine.startsWith('//'))
64
+ continue;
65
+ const pkgMatch = importLine.match(/"([^"]+)"/);
66
+ if (pkgMatch) {
67
+ imports.push({
68
+ module: pkgMatch[1],
69
+ names: [],
70
+ line: k + 1,
71
+ isDynamic: false,
72
+ });
73
+ }
74
+ }
75
+ i = j;
76
+ }
77
+ }
78
+ return imports;
79
+ }
80
+ extractErrorHandlers(source) {
81
+ const handlers = [];
82
+ const lines = source.split('\n');
83
+ for (let i = 0; i < lines.length; i++) {
84
+ const line = lines[i];
85
+ // Match: if err != nil {
86
+ if (/if\s+err\s*!=\s*nil\s*\{/.test(line)) {
87
+ const body = this.extractBraceBody(lines, i).join('\n');
88
+ const strategy = this.classifyGoErrorStrategy(body);
89
+ handlers.push({
90
+ type: 'if-err',
91
+ strategy,
92
+ startLine: i + 1,
93
+ body,
94
+ });
95
+ }
96
+ }
97
+ return handlers;
98
+ }
99
+ extractNamingPatterns(source) {
100
+ const patterns = [];
101
+ const lines = source.split('\n');
102
+ for (let i = 0; i < lines.length; i++) {
103
+ const line = lines[i];
104
+ // Function definitions
105
+ const funcMatch = line.match(/^\s*func\s+(?:\([^)]+\)\s+)?(\w+)\s*\(/);
106
+ if (funcMatch) {
107
+ const name = funcMatch[1];
108
+ patterns.push({
109
+ name,
110
+ kind: 'function',
111
+ convention: classifyCasing(name),
112
+ });
113
+ continue;
114
+ }
115
+ // Const/var declarations
116
+ const varMatch = line.match(/^\s*(?:const|var)\s+(\w+)\s*=/);
117
+ if (varMatch) {
118
+ const name = varMatch[1];
119
+ const kind = line.includes('const') ? 'constant' : 'variable';
120
+ patterns.push({
121
+ name,
122
+ kind,
123
+ convention: classifyCasing(name),
124
+ });
125
+ }
126
+ }
127
+ return patterns;
128
+ }
129
+ stripComments(source) {
130
+ // Remove line comments: //
131
+ let result = source.replace(/\/\/.*/g, '');
132
+ // Remove block comments: /* */
133
+ result = result.replace(/\/\*[\s\S]*?\*\//g, '');
134
+ return result;
135
+ }
136
+ extractComparisonOps(source) {
137
+ const ops = [];
138
+ const cleaned = this.stripComments(source);
139
+ const matches = cleaned.matchAll(/(===|!==|==|!=|>=|<=|>(?!=)|<(?!=))/g);
140
+ for (const m of matches) {
141
+ ops.push(m[1]);
142
+ }
143
+ return ops;
144
+ }
145
+ countBranches(source) {
146
+ let count = 0;
147
+ const cleaned = this.stripComments(source);
148
+ count += (cleaned.match(/\bif\s+/g) || []).length;
149
+ count += (cleaned.match(/\belse\s+if\s+/g) || []).length;
150
+ count += (cleaned.match(/\belse\s*\{/g) || []).length;
151
+ count += (cleaned.match(/\bswitch\s/g) || []).length;
152
+ count += (cleaned.match(/\bcase\s+/g) || []).length;
153
+ count += (cleaned.match(/\bselect\s*\{/g) || []).length;
154
+ return count;
155
+ }
156
+ countReturns(source) {
157
+ return (source.match(/\breturn\b/g) || []).length;
158
+ }
159
+ extractBraceBody(lines, startIndex) {
160
+ let braceDepth = 0;
161
+ let started = false;
162
+ const body = [];
163
+ for (let i = startIndex; i < lines.length; i++) {
164
+ const line = lines[i];
165
+ for (const ch of line) {
166
+ if (ch === '{') {
167
+ braceDepth++;
168
+ started = true;
169
+ }
170
+ if (ch === '}')
171
+ braceDepth--;
172
+ }
173
+ if (started)
174
+ body.push(line);
175
+ if (started && braceDepth === 0)
176
+ break;
177
+ }
178
+ return body;
179
+ }
180
+ classifyGoErrorStrategy(body) {
181
+ const trimmed = body.trim();
182
+ if (!trimmed)
183
+ return 'swallow';
184
+ if (/\breturn\b.*\berr\b/.test(trimmed))
185
+ return 'return-error';
186
+ if (/\breturn\b.*fmt\.Errorf|errors\.Wrap/.test(trimmed))
187
+ return 'wrap';
188
+ if (/\bpanic\b/.test(trimmed))
189
+ return 'panic';
190
+ if (/\blog\b/.test(trimmed))
191
+ return 'log';
192
+ return 'other';
193
+ }
194
+ }
195
+ export const goAdapter = new GoAdapter();
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Language Adapters — Barrel Export
3
+ *
4
+ * Single entry point for the language adapter layer.
5
+ * Gates import from here: `import { languageAdapters } from './language-adapters/index.js'`
6
+ */
7
+ export * from './types.js';
8
+ export * from './registry.js';
9
+ export { jsAdapter } from './js-adapter.js';
10
+ export { pythonAdapter } from './python-adapter.js';
11
+ export { goAdapter } from './go-adapter.js';
12
+ export { rubyAdapter } from './ruby-adapter.js';
13
+ export { rustAdapter } from './rust-adapter.js';
14
+ export { csharpAdapter } from './csharp-adapter.js';
15
+ export { javaAdapter } from './java-adapter.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Language Adapters — Barrel Export
3
+ *
4
+ * Single entry point for the language adapter layer.
5
+ * Gates import from here: `import { languageAdapters } from './language-adapters/index.js'`
6
+ */
7
+ export * from './types.js';
8
+ export * from './registry.js';
9
+ // Individual adapters (for direct use if needed)
10
+ export { jsAdapter } from './js-adapter.js';
11
+ export { pythonAdapter } from './python-adapter.js';
12
+ export { goAdapter } from './go-adapter.js';
13
+ export { rubyAdapter } from './ruby-adapter.js';
14
+ export { rustAdapter } from './rust-adapter.js';
15
+ export { csharpAdapter } from './csharp-adapter.js';
16
+ export { javaAdapter } from './java-adapter.js';
@@ -0,0 +1,16 @@
1
+ import type { LanguageAdapter, FunctionFact, ImportFact, ErrorHandlerFact, NamingPattern } from './types.js';
2
+ declare class JavaAdapter implements LanguageAdapter {
3
+ readonly id = "java";
4
+ readonly name = "Java/Kotlin";
5
+ readonly extensions: string[];
6
+ extractFunctions(source: string): FunctionFact[];
7
+ extractImports(source: string): ImportFact[];
8
+ extractErrorHandlers(source: string): ErrorHandlerFact[];
9
+ extractNamingPatterns(source: string): NamingPattern[];
10
+ stripComments(source: string): string;
11
+ extractComparisonOps(source: string): string[];
12
+ countBranches(source: string): number;
13
+ countReturns(source: string): number;
14
+ }
15
+ export declare const javaAdapter: JavaAdapter;
16
+ export {};