skrypt-ai 0.5.0 → 0.6.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 (120) hide show
  1. package/dist/auth/index.js +8 -1
  2. package/dist/autofix/index.d.ts +0 -4
  3. package/dist/autofix/index.js +0 -21
  4. package/dist/capture/browser.d.ts +11 -0
  5. package/dist/capture/browser.js +173 -0
  6. package/dist/capture/diff.d.ts +23 -0
  7. package/dist/capture/diff.js +52 -0
  8. package/dist/capture/index.d.ts +23 -0
  9. package/dist/capture/index.js +210 -0
  10. package/dist/capture/naming.d.ts +17 -0
  11. package/dist/capture/naming.js +45 -0
  12. package/dist/capture/parser.d.ts +15 -0
  13. package/dist/capture/parser.js +80 -0
  14. package/dist/capture/types.d.ts +57 -0
  15. package/dist/capture/types.js +1 -0
  16. package/dist/cli.js +4 -0
  17. package/dist/commands/autofix.js +136 -120
  18. package/dist/commands/cron.js +58 -47
  19. package/dist/commands/deploy.js +123 -102
  20. package/dist/commands/generate.js +88 -6
  21. package/dist/commands/heal.d.ts +10 -0
  22. package/dist/commands/heal.js +201 -0
  23. package/dist/commands/i18n.js +146 -111
  24. package/dist/commands/lint.js +50 -44
  25. package/dist/commands/llms-txt.js +59 -49
  26. package/dist/commands/login.js +61 -43
  27. package/dist/commands/mcp.js +6 -0
  28. package/dist/commands/monitor.js +13 -8
  29. package/dist/commands/qa.d.ts +2 -0
  30. package/dist/commands/qa.js +43 -0
  31. package/dist/commands/review-pr.js +108 -102
  32. package/dist/commands/sdk.js +128 -122
  33. package/dist/commands/security.js +86 -80
  34. package/dist/commands/test.js +91 -92
  35. package/dist/commands/version.js +104 -75
  36. package/dist/commands/watch.js +130 -114
  37. package/dist/config/types.js +2 -2
  38. package/dist/context-hub/index.d.ts +23 -0
  39. package/dist/context-hub/index.js +179 -0
  40. package/dist/context-hub/mappings.d.ts +8 -0
  41. package/dist/context-hub/mappings.js +55 -0
  42. package/dist/context-hub/types.d.ts +33 -0
  43. package/dist/context-hub/types.js +1 -0
  44. package/dist/generator/generator.js +39 -6
  45. package/dist/generator/types.d.ts +7 -0
  46. package/dist/generator/writer.d.ts +3 -1
  47. package/dist/generator/writer.js +24 -4
  48. package/dist/llm/anthropic-client.d.ts +1 -0
  49. package/dist/llm/anthropic-client.js +3 -1
  50. package/dist/llm/index.d.ts +6 -4
  51. package/dist/llm/index.js +76 -261
  52. package/dist/llm/openai-client.d.ts +1 -0
  53. package/dist/llm/openai-client.js +7 -2
  54. package/dist/qa/checks.d.ts +10 -0
  55. package/dist/qa/checks.js +492 -0
  56. package/dist/qa/fixes.d.ts +30 -0
  57. package/dist/qa/fixes.js +277 -0
  58. package/dist/qa/index.d.ts +29 -0
  59. package/dist/qa/index.js +187 -0
  60. package/dist/qa/types.d.ts +24 -0
  61. package/dist/qa/types.js +1 -0
  62. package/dist/scanner/csharp.d.ts +23 -0
  63. package/dist/scanner/csharp.js +421 -0
  64. package/dist/scanner/index.js +16 -2
  65. package/dist/scanner/java.d.ts +39 -0
  66. package/dist/scanner/java.js +318 -0
  67. package/dist/scanner/kotlin.d.ts +23 -0
  68. package/dist/scanner/kotlin.js +389 -0
  69. package/dist/scanner/php.d.ts +57 -0
  70. package/dist/scanner/php.js +351 -0
  71. package/dist/scanner/ruby.d.ts +36 -0
  72. package/dist/scanner/ruby.js +431 -0
  73. package/dist/scanner/swift.d.ts +25 -0
  74. package/dist/scanner/swift.js +392 -0
  75. package/dist/scanner/types.d.ts +1 -1
  76. package/dist/template/content/docs/_navigation.json +46 -0
  77. package/dist/template/content/docs/_sidebars.json +684 -0
  78. package/dist/template/content/docs/core.md +4544 -0
  79. package/dist/template/content/docs/index.mdx +89 -0
  80. package/dist/template/content/docs/integrations.md +1158 -0
  81. package/dist/template/content/docs/llms-full.md +403 -0
  82. package/dist/template/content/docs/llms.txt +4588 -0
  83. package/dist/template/content/docs/other.md +10379 -0
  84. package/dist/template/content/docs/tools.md +746 -0
  85. package/dist/template/content/docs/types.md +531 -0
  86. package/dist/template/docs.json +13 -11
  87. package/dist/template/mdx-components.tsx +27 -2
  88. package/dist/template/package.json +6 -0
  89. package/dist/template/public/search-index.json +1 -1
  90. package/dist/template/scripts/build-search-index.mjs +84 -6
  91. package/dist/template/src/app/api/chat/route.ts +83 -128
  92. package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
  93. package/dist/template/src/app/docs/llms-full.md +151 -4
  94. package/dist/template/src/app/docs/llms.txt +2464 -847
  95. package/dist/template/src/app/docs/page.mdx +48 -38
  96. package/dist/template/src/app/layout.tsx +3 -1
  97. package/dist/template/src/app/page.tsx +22 -8
  98. package/dist/template/src/components/ai-chat.tsx +73 -64
  99. package/dist/template/src/components/breadcrumbs.tsx +21 -23
  100. package/dist/template/src/components/copy-button.tsx +13 -9
  101. package/dist/template/src/components/copy-page-button.tsx +54 -0
  102. package/dist/template/src/components/docs-layout.tsx +37 -25
  103. package/dist/template/src/components/header.tsx +51 -10
  104. package/dist/template/src/components/mdx/card.tsx +17 -3
  105. package/dist/template/src/components/mdx/code-block.tsx +13 -9
  106. package/dist/template/src/components/mdx/code-group.tsx +13 -8
  107. package/dist/template/src/components/mdx/heading.tsx +15 -2
  108. package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
  109. package/dist/template/src/components/mdx/index.tsx +2 -0
  110. package/dist/template/src/components/mdx/mermaid.tsx +110 -0
  111. package/dist/template/src/components/mdx/screenshot.tsx +150 -0
  112. package/dist/template/src/components/scroll-to-hash.tsx +48 -0
  113. package/dist/template/src/components/sidebar.tsx +12 -18
  114. package/dist/template/src/components/table-of-contents.tsx +9 -0
  115. package/dist/template/src/lib/highlight.ts +3 -88
  116. package/dist/template/src/lib/navigation.ts +159 -0
  117. package/dist/template/src/styles/globals.css +17 -6
  118. package/dist/utils/validation.d.ts +0 -3
  119. package/dist/utils/validation.js +0 -26
  120. package/package.json +3 -2
@@ -0,0 +1,421 @@
1
+ import { readFileSync } from 'fs';
2
+ /**
3
+ * Scanner for C# source files
4
+ * Extracts: public classes, interfaces, enums, structs, records, methods
5
+ */
6
+ export class CSharpScanner {
7
+ languages = ['csharp'];
8
+ canHandle(filePath) {
9
+ return (/\.cs$/.test(filePath) &&
10
+ !filePath.endsWith('Test.cs') &&
11
+ !filePath.endsWith('Tests.cs') &&
12
+ !filePath.includes('/Tests/') &&
13
+ !filePath.includes('/test/') &&
14
+ !filePath.includes('\\Tests\\') &&
15
+ !filePath.includes('\\test\\'));
16
+ }
17
+ async scanFile(filePath) {
18
+ try {
19
+ const source = readFileSync(filePath, 'utf-8');
20
+ const elements = [];
21
+ const errors = [];
22
+ const lines = source.split('\n');
23
+ // Extract namespace
24
+ const namespaceMatch = source.match(/^namespace\s+([\w.]+)/m);
25
+ const packageName = namespaceMatch?.[1] ?? 'unknown';
26
+ // Extract using statements for context
27
+ const imports = this.extractImports(source);
28
+ // Find all public types and methods
29
+ this.extractTypes(source, lines, filePath, packageName, imports, elements);
30
+ this.extractMethods(source, lines, filePath, packageName, imports, elements);
31
+ return {
32
+ filePath,
33
+ language: 'csharp',
34
+ elements,
35
+ errors
36
+ };
37
+ }
38
+ catch (err) {
39
+ return {
40
+ filePath,
41
+ language: 'csharp',
42
+ elements: [],
43
+ errors: [`Failed to parse: ${err}`]
44
+ };
45
+ }
46
+ }
47
+ extractImports(source) {
48
+ const imports = [];
49
+ const regex = /^using\s+([^;]+);/gm;
50
+ let match;
51
+ while ((match = regex.exec(source)) !== null) {
52
+ if (match[1])
53
+ imports.push(match[1]);
54
+ }
55
+ return imports;
56
+ }
57
+ extractTypes(source, lines, filePath, packageName, imports, elements) {
58
+ // Match: public class/interface/enum/struct/record TypeName
59
+ // Optionally with generic params, base class, interfaces
60
+ const typeRegex = /^[ \t]*public\s+(?:(?:abstract|sealed|static|partial)\s+)*(?:(class|interface|enum|struct|record))\s+(\w+)\s*/gm;
61
+ let match;
62
+ while ((match = typeRegex.exec(source)) !== null) {
63
+ const kind = match[1];
64
+ const name = match[2];
65
+ if (!kind || !name)
66
+ continue;
67
+ // Extract generics with depth counting to handle nested generics
68
+ const afterName = match.index + match[0].length;
69
+ const generics = this.extractGenerics(source, afterName);
70
+ const lineNumber = this.getLineNumber(source, match.index);
71
+ const docstring = this.getDocComment(lines, lineNumber - 1);
72
+ // For records with primary constructor params, extract them
73
+ let parameters = [];
74
+ if (kind === 'record') {
75
+ const recordParamMatch = source.slice(match.index).match(/public\s+(?:(?:abstract|sealed|static|partial)\s+)*record\s+\w+\s*(?:<[^>]+>)?\s*\(([^)]*)\)/);
76
+ if (recordParamMatch?.[1]) {
77
+ parameters = this.parseCSharpParams(recordParamMatch[1]);
78
+ }
79
+ }
80
+ const signature = `public ${kind} ${name}${generics}`;
81
+ elements.push({
82
+ kind: 'class', // Using 'class' for all C# types
83
+ name,
84
+ signature,
85
+ parameters,
86
+ docstring,
87
+ filePath,
88
+ lineNumber,
89
+ isExported: true,
90
+ isPublic: true,
91
+ imports,
92
+ packageName,
93
+ sourceContext: this.getSourceContext(lines, lineNumber, 15)
94
+ });
95
+ }
96
+ }
97
+ extractMethods(source, lines, filePath, packageName, imports, elements) {
98
+ // We need to find which class each method belongs to.
99
+ // First, find all class/struct/record blocks and their ranges.
100
+ const classRanges = this.findClassRanges(source);
101
+ // Match public methods (instance or static, sync or async)
102
+ // Patterns:
103
+ // public ReturnType MethodName(params)
104
+ // public static ReturnType MethodName(params)
105
+ // public async Task<T> MethodName(params)
106
+ // public override ReturnType MethodName(params)
107
+ // public virtual ReturnType MethodName(params)
108
+ // Exclude constructors (name matches class name) — we include them as methods
109
+ // Exclude property accessors, event handlers
110
+ const methodRegex = /^[ \t]*public\s+((?:(?:static|async|virtual|override|abstract|sealed|new)\s+)*)(\w+)/gm;
111
+ let match;
112
+ while ((match = methodRegex.exec(source)) !== null) {
113
+ const modifiers = match[1]?.trim() || '';
114
+ const baseReturnType = match[2];
115
+ if (!baseReturnType)
116
+ continue;
117
+ // After the base return type, extract any generics with depth counting
118
+ let pos = match.index + match[0].length;
119
+ const returnGenerics = this.extractGenerics(source, pos);
120
+ pos += returnGenerics.length;
121
+ const returnType = baseReturnType + returnGenerics;
122
+ // Skip whitespace
123
+ while (pos < source.length && (source[pos] === ' ' || source[pos] === '\t'))
124
+ pos++;
125
+ // Next token should be the method name (identifier)
126
+ const nameMatch = source.slice(pos).match(/^(\w+)\s*\(/);
127
+ if (!nameMatch || !nameMatch[1])
128
+ continue;
129
+ const name = nameMatch[1];
130
+ pos += nameMatch[0].length - 1; // position at '('
131
+ // Extract params up to the matching closing paren
132
+ const paramsStart = pos + 1;
133
+ let parenDepth = 1;
134
+ let parenPos = paramsStart;
135
+ while (parenPos < source.length && parenDepth > 0) {
136
+ if (source[parenPos] === '(')
137
+ parenDepth++;
138
+ else if (source[parenPos] === ')')
139
+ parenDepth--;
140
+ parenPos++;
141
+ }
142
+ const paramsStr = source.slice(paramsStart, parenPos - 1);
143
+ if (paramsStr === undefined)
144
+ continue;
145
+ // Skip type declarations (class, interface, enum, struct, record)
146
+ if (returnType === 'class' ||
147
+ returnType === 'interface' ||
148
+ returnType === 'enum' ||
149
+ returnType === 'struct' ||
150
+ returnType === 'record') {
151
+ continue;
152
+ }
153
+ const lineNumber = this.getLineNumber(source, match.index);
154
+ const docstring = this.getDocComment(lines, lineNumber - 1);
155
+ const parameters = this.parseCSharpParams(paramsStr);
156
+ const isAsync = modifiers.includes('async');
157
+ // Find parent class
158
+ const parentClass = this.findParentClass(match.index, classRanges);
159
+ const fullModifiers = modifiers ? `${modifiers} ` : '';
160
+ const signature = `public ${fullModifiers}${returnType} ${name}(${paramsStr})`;
161
+ elements.push({
162
+ kind: 'method',
163
+ name,
164
+ signature,
165
+ parameters,
166
+ returnType: returnType || undefined,
167
+ docstring,
168
+ filePath,
169
+ lineNumber,
170
+ parentClass,
171
+ isAsync,
172
+ isExported: true,
173
+ isPublic: true,
174
+ imports,
175
+ packageName,
176
+ sourceContext: this.getSourceContext(lines, lineNumber)
177
+ });
178
+ }
179
+ // Also extract interface method signatures (no body, just declarations)
180
+ this.extractInterfaceMethods(source, lines, filePath, packageName, imports, elements, classRanges);
181
+ }
182
+ extractInterfaceMethods(source, lines, filePath, packageName, imports, elements, classRanges) {
183
+ // Interface methods don't have access modifiers in C#
184
+ // They look like: ReturnType MethodName(params);
185
+ // We only extract these inside interface blocks
186
+ const interfaceRanges = classRanges.filter(r => r.kind === 'interface');
187
+ for (const range of interfaceRanges) {
188
+ const body = source.slice(range.bodyStart, range.bodyEnd);
189
+ const methodRegex = /^[ \t]*(\w+)/gm;
190
+ let match;
191
+ while ((match = methodRegex.exec(body)) !== null) {
192
+ const baseReturnType = match[1];
193
+ if (!baseReturnType)
194
+ continue;
195
+ // Skip lines that look like properties or non-method declarations
196
+ if (baseReturnType === 'get' || baseReturnType === 'set' || baseReturnType === '//' || baseReturnType === '///')
197
+ continue;
198
+ // Extract generics for return type
199
+ let pos = match.index + match[0].length;
200
+ const returnGenerics = this.extractGenerics(body, pos);
201
+ pos += returnGenerics.length;
202
+ const returnType = baseReturnType + returnGenerics;
203
+ // Skip whitespace
204
+ while (pos < body.length && (body[pos] === ' ' || body[pos] === '\t'))
205
+ pos++;
206
+ // Next should be method name followed by '('
207
+ const nameMatch = body.slice(pos).match(/^(\w+)\s*\(/);
208
+ if (!nameMatch || !nameMatch[1])
209
+ continue;
210
+ const name = nameMatch[1];
211
+ pos += nameMatch[0].length - 1; // position at '('
212
+ // Extract params
213
+ const paramsStart = pos + 1;
214
+ let parenDepth = 1;
215
+ let parenPos = paramsStart;
216
+ while (parenPos < body.length && parenDepth > 0) {
217
+ if (body[parenPos] === '(')
218
+ parenDepth++;
219
+ else if (body[parenPos] === ')')
220
+ parenDepth--;
221
+ parenPos++;
222
+ }
223
+ const paramsStr = body.slice(paramsStart, parenPos - 1);
224
+ // Must end with semicolon (interface method declaration)
225
+ const afterParen = body.slice(parenPos - 1).match(/^\)\s*;/);
226
+ if (!afterParen)
227
+ continue;
228
+ if (paramsStr === undefined)
229
+ continue;
230
+ const absoluteIndex = range.bodyStart + match.index;
231
+ const lineNumber = this.getLineNumber(source, absoluteIndex);
232
+ const docstring = this.getDocComment(lines, lineNumber - 1);
233
+ const parameters = this.parseCSharpParams(paramsStr);
234
+ const signature = `${returnType} ${name}(${paramsStr})`;
235
+ elements.push({
236
+ kind: 'method',
237
+ name,
238
+ signature,
239
+ parameters,
240
+ returnType: returnType || undefined,
241
+ docstring,
242
+ filePath,
243
+ lineNumber,
244
+ parentClass: range.name,
245
+ isAsync: false,
246
+ isExported: true,
247
+ isPublic: true,
248
+ imports,
249
+ packageName,
250
+ sourceContext: this.getSourceContext(lines, lineNumber)
251
+ });
252
+ }
253
+ }
254
+ }
255
+ findClassRanges(source) {
256
+ const ranges = [];
257
+ const typeRegex = /^[ \t]*public\s+(?:(?:abstract|sealed|static|partial)\s+)*(?:(class|interface|enum|struct|record))\s+(\w+)/gm;
258
+ let match;
259
+ while ((match = typeRegex.exec(source)) !== null) {
260
+ const kind = match[1];
261
+ const name = match[2];
262
+ if (!kind || !name)
263
+ continue;
264
+ // Find the opening brace after this match
265
+ // But first check if a semicolon comes before the brace (e.g., single-line records)
266
+ const afterMatchStart = match.index + match[0].length;
267
+ const afterMatch = source.indexOf('{', afterMatchStart);
268
+ if (afterMatch === -1)
269
+ continue;
270
+ const semicolonBefore = source.indexOf(';', afterMatchStart);
271
+ if (semicolonBefore !== -1 && semicolonBefore < afterMatch)
272
+ continue;
273
+ // Find matching closing brace
274
+ const bodyEnd = this.findMatchingBrace(source, afterMatch);
275
+ if (bodyEnd === -1)
276
+ continue;
277
+ ranges.push({
278
+ name,
279
+ kind,
280
+ start: match.index,
281
+ bodyStart: afterMatch + 1,
282
+ bodyEnd
283
+ });
284
+ }
285
+ return ranges;
286
+ }
287
+ findMatchingBrace(source, openIndex) {
288
+ let depth = 0;
289
+ for (let i = openIndex; i < source.length; i++) {
290
+ if (source[i] === '{')
291
+ depth++;
292
+ else if (source[i] === '}') {
293
+ depth--;
294
+ if (depth === 0)
295
+ return i;
296
+ }
297
+ }
298
+ return -1;
299
+ }
300
+ findParentClass(index, classRanges) {
301
+ for (const range of classRanges) {
302
+ if (index > range.bodyStart && index < range.bodyEnd) {
303
+ return range.name;
304
+ }
305
+ }
306
+ return undefined;
307
+ }
308
+ parseCSharpParams(paramsStr) {
309
+ if (!paramsStr.trim())
310
+ return [];
311
+ const params = [];
312
+ const parts = this.splitParams(paramsStr);
313
+ for (const part of parts) {
314
+ const trimmed = part.trim();
315
+ if (!trimmed)
316
+ continue;
317
+ // Remove parameter modifiers: ref, out, in, params, this
318
+ let cleaned = trimmed.replace(/^(?:ref|out|in|params|this)\s+/, '');
319
+ // Format: "Type name" or "Type name = default"
320
+ const defaultMatch = cleaned.match(/^(.+?)\s*=\s*(.+)$/);
321
+ let defaultValue;
322
+ if (defaultMatch) {
323
+ cleaned = defaultMatch[1] ?? cleaned;
324
+ defaultValue = defaultMatch[2];
325
+ }
326
+ // Split into type and name: last word is name, rest is type
327
+ const lastSpace = cleaned.lastIndexOf(' ');
328
+ if (lastSpace > 0) {
329
+ const type = cleaned.slice(0, lastSpace).trim();
330
+ const name = cleaned.slice(lastSpace + 1).trim();
331
+ params.push({ name, type, default: defaultValue });
332
+ }
333
+ else {
334
+ // Just a name or type
335
+ params.push({ name: cleaned, type: undefined });
336
+ }
337
+ }
338
+ return params;
339
+ }
340
+ splitParams(str) {
341
+ const parts = [];
342
+ let depth = 0;
343
+ let current = '';
344
+ for (const char of str) {
345
+ if (char === '<' || char === '(' || char === '[' || char === '{')
346
+ depth++;
347
+ else if (char === '>' || char === ')' || char === ']' || char === '}')
348
+ depth--;
349
+ else if (char === ',' && depth === 0) {
350
+ parts.push(current);
351
+ current = '';
352
+ continue;
353
+ }
354
+ current += char;
355
+ }
356
+ if (current.trim())
357
+ parts.push(current);
358
+ return parts;
359
+ }
360
+ getLineNumber(source, index) {
361
+ return source.slice(0, index).split('\n').length;
362
+ }
363
+ getDocComment(lines, lineIndex) {
364
+ const comments = [];
365
+ let i = lineIndex - 1;
366
+ while (i >= 0) {
367
+ const lineContent = lines[i];
368
+ if (!lineContent)
369
+ break;
370
+ const line = lineContent.trim();
371
+ if (line.startsWith('///')) {
372
+ // XML doc comment line
373
+ let content = line.replace(/^\/\/\/\s?/, '');
374
+ // Strip XML tags like <summary>, </summary>, <param>, <returns>
375
+ content = content
376
+ .replace(/<\/?summary>/g, '')
377
+ .replace(/<\/?remarks>/g, '')
378
+ .replace(/<\/?returns>/g, '')
379
+ .replace(/<param\s+name="[^"]*">/g, '')
380
+ .replace(/<\/param>/g, '')
381
+ .trim();
382
+ if (content) {
383
+ comments.unshift(content);
384
+ }
385
+ i--;
386
+ }
387
+ else if (line === '') {
388
+ i--;
389
+ }
390
+ else if (line.startsWith('[') && line.endsWith(']')) {
391
+ i--;
392
+ }
393
+ else {
394
+ break;
395
+ }
396
+ }
397
+ return comments.length > 0 ? comments.join('\n') : undefined;
398
+ }
399
+ extractGenerics(source, startIndex) {
400
+ if (startIndex >= source.length || source[startIndex] !== '<')
401
+ return '';
402
+ let depth = 0;
403
+ let i = startIndex;
404
+ while (i < source.length) {
405
+ if (source[i] === '<')
406
+ depth++;
407
+ else if (source[i] === '>') {
408
+ depth--;
409
+ if (depth === 0)
410
+ return source.slice(startIndex, i + 1);
411
+ }
412
+ i++;
413
+ }
414
+ return '';
415
+ }
416
+ getSourceContext(lines, lineNumber, context = 5) {
417
+ const start = Math.max(0, lineNumber - context - 1);
418
+ const end = Math.min(lines.length, lineNumber + context);
419
+ return lines.slice(start, end).join('\n');
420
+ }
421
+ }
@@ -4,6 +4,12 @@ import { PythonScanner } from './python.js';
4
4
  import { TypeScriptScanner } from './typescript.js';
5
5
  import { GoScanner } from './go.js';
6
6
  import { RustScanner } from './rust.js';
7
+ import { JavaScanner } from './java.js';
8
+ import { CSharpScanner } from './csharp.js';
9
+ import { PHPScanner } from './php.js';
10
+ import { KotlinScanner } from './kotlin.js';
11
+ import { SwiftScanner } from './swift.js';
12
+ import { RubyScanner } from './ruby.js';
7
13
  export * from './types.js';
8
14
  export * from './content-type.js';
9
15
  // All available scanners
@@ -12,6 +18,12 @@ const SCANNERS = [
12
18
  new TypeScriptScanner(),
13
19
  new GoScanner(),
14
20
  new RustScanner(),
21
+ new JavaScanner(),
22
+ new CSharpScanner(),
23
+ new PHPScanner(),
24
+ new KotlinScanner(),
25
+ new SwiftScanner(),
26
+ new RubyScanner(),
15
27
  ];
16
28
  /**
17
29
  * Get the appropriate scanner for a file
@@ -105,8 +117,8 @@ async function findFiles(dir, include, exclude) {
105
117
  * Scan a directory (or single file) for all API elements
106
118
  */
107
119
  export async function scanDirectory(dir, options = {}) {
108
- const include = options.include || ['**/*.py', '**/*.ts', '**/*.js', '**/*.go', '**/*.rs'];
109
- const exclude = options.exclude || ['**/node_modules/**', '**/__pycache__/**', '**/dist/**'];
120
+ const include = options.include || ['**/*.py', '**/*.ts', '**/*.js', '**/*.go', '**/*.rs', '**/*.java', '**/*.cs', '**/*.php', '**/*.kt', '**/*.kts', '**/*.swift', '**/*.rb'];
121
+ const exclude = options.exclude || ['**/node_modules/**', '**/__pycache__/**', '**/dist/**', '**/target/**', '**/vendor/**', '**/build/**', '**/bin/**', '**/obj/**', '**/.build/**'];
110
122
  // Check if input is a file or directory
111
123
  const stats = await stat(dir);
112
124
  let files;
@@ -152,6 +164,8 @@ export async function scanFile(filePath) {
152
164
  const langMap = {
153
165
  ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
154
166
  py: 'python', go: 'go', rs: 'rust',
167
+ java: 'java', cs: 'csharp', php: 'php',
168
+ kt: 'kotlin', kts: 'kotlin', swift: 'swift', rb: 'ruby',
155
169
  };
156
170
  const language = langMap[ext] ?? 'typescript';
157
171
  return {
@@ -0,0 +1,39 @@
1
+ import { Scanner, ScanResult } from './types.js';
2
+ /**
3
+ * Scanner for Java source files
4
+ * Extracts: public classes, public methods, public static methods
5
+ */
6
+ export declare class JavaScanner implements Scanner {
7
+ languages: string[];
8
+ canHandle(filePath: string): boolean;
9
+ scanFile(filePath: string): Promise<ScanResult>;
10
+ private extractPackage;
11
+ private extractImports;
12
+ /**
13
+ * Extracts the full generics string starting at startIndex by counting `<>` depth.
14
+ * Returns empty string if source[startIndex] is not '<'.
15
+ */
16
+ private extractGenerics;
17
+ private extractClasses;
18
+ private extractMethods;
19
+ /**
20
+ * Extracts interface methods that don't have explicit `public` modifier.
21
+ * In Java, interface methods are implicitly public.
22
+ */
23
+ private extractInterfaceMethods;
24
+ /**
25
+ * Finds all class/interface/enum/record declarations and their brace-delimited ranges.
26
+ */
27
+ private findClassRanges;
28
+ private findMatchingBrace;
29
+ /**
30
+ * Finds the innermost class that contains the given source index,
31
+ * using brace-depth-aware class ranges.
32
+ */
33
+ private findParentClass;
34
+ private parseParams;
35
+ private splitParams;
36
+ private getLineNumber;
37
+ private getJavadoc;
38
+ private getSourceContext;
39
+ }