@principal-ai/codebase-composition 0.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 (129) hide show
  1. package/README.md +67 -0
  2. package/dist/index.d.ts +9 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +23 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/modules/DependencyLayerModule.d.ts +44 -0
  7. package/dist/modules/DependencyLayerModule.d.ts.map +1 -0
  8. package/dist/modules/DependencyLayerModule.js +286 -0
  9. package/dist/modules/DependencyLayerModule.js.map +1 -0
  10. package/dist/modules/FileSystemModule.d.ts +30 -0
  11. package/dist/modules/FileSystemModule.d.ts.map +1 -0
  12. package/dist/modules/FileSystemModule.js +46 -0
  13. package/dist/modules/FileSystemModule.js.map +1 -0
  14. package/dist/modules/FileTypeLayerModule.d.ts +34 -0
  15. package/dist/modules/FileTypeLayerModule.d.ts.map +1 -0
  16. package/dist/modules/FileTypeLayerModule.js +169 -0
  17. package/dist/modules/FileTypeLayerModule.js.map +1 -0
  18. package/dist/modules/FrameworkLayerModule.d.ts +22 -0
  19. package/dist/modules/FrameworkLayerModule.d.ts.map +1 -0
  20. package/dist/modules/FrameworkLayerModule.js +388 -0
  21. package/dist/modules/FrameworkLayerModule.js.map +1 -0
  22. package/dist/modules/PackageLayerModule.d.ts +23 -0
  23. package/dist/modules/PackageLayerModule.d.ts.map +1 -0
  24. package/dist/modules/PackageLayerModule.js +810 -0
  25. package/dist/modules/PackageLayerModule.js.map +1 -0
  26. package/dist/modules/TypeExtractionModule.d.ts +37 -0
  27. package/dist/modules/TypeExtractionModule.d.ts.map +1 -0
  28. package/dist/modules/TypeExtractionModule.js +180 -0
  29. package/dist/modules/TypeExtractionModule.js.map +1 -0
  30. package/dist/modules/VersionControlLayerModule.d.ts +10 -0
  31. package/dist/modules/VersionControlLayerModule.d.ts.map +1 -0
  32. package/dist/modules/VersionControlLayerModule.js +32 -0
  33. package/dist/modules/VersionControlLayerModule.js.map +1 -0
  34. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/index.d.ts +4 -0
  35. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/index.d.ts.map +1 -0
  36. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/index.js +7 -0
  37. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/index.js.map +1 -0
  38. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/category.d.ts +15 -0
  39. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/category.d.ts.map +1 -0
  40. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/category.js +3 -0
  41. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/category.js.map +1 -0
  42. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/product.d.ts +34 -0
  43. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/product.d.ts.map +1 -0
  44. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/product.js +23 -0
  45. package/dist/modules/__fixtures__/typescript-packages/complex-types/src/models/product.js.map +1 -0
  46. package/dist/modules/__fixtures__/typescript-packages/simple-types/index.d.ts +39 -0
  47. package/dist/modules/__fixtures__/typescript-packages/simple-types/index.d.ts.map +1 -0
  48. package/dist/modules/__fixtures__/typescript-packages/simple-types/index.js +39 -0
  49. package/dist/modules/__fixtures__/typescript-packages/simple-types/index.js.map +1 -0
  50. package/dist/modules/extractors/TypeScriptExtractor.d.ts +18 -0
  51. package/dist/modules/extractors/TypeScriptExtractor.d.ts.map +1 -0
  52. package/dist/modules/extractors/TypeScriptExtractor.js +361 -0
  53. package/dist/modules/extractors/TypeScriptExtractor.js.map +1 -0
  54. package/dist/modules/index.d.ts +13 -0
  55. package/dist/modules/index.d.ts.map +1 -0
  56. package/dist/modules/index.js +21 -0
  57. package/dist/modules/index.js.map +1 -0
  58. package/dist/providers/GitVersionControlProvider.d.ts +108 -0
  59. package/dist/providers/GitVersionControlProvider.d.ts.map +1 -0
  60. package/dist/providers/GitVersionControlProvider.js +380 -0
  61. package/dist/providers/GitVersionControlProvider.js.map +1 -0
  62. package/dist/providers/PackageManagerApiProvider.d.ts +78 -0
  63. package/dist/providers/PackageManagerApiProvider.d.ts.map +1 -0
  64. package/dist/providers/PackageManagerApiProvider.js +14 -0
  65. package/dist/providers/PackageManagerApiProvider.js.map +1 -0
  66. package/dist/providers/index.d.ts +4 -0
  67. package/dist/providers/index.d.ts.map +1 -0
  68. package/dist/providers/index.js +10 -0
  69. package/dist/providers/index.js.map +1 -0
  70. package/dist/services/FilesystemService.d.ts +59 -0
  71. package/dist/services/FilesystemService.d.ts.map +1 -0
  72. package/dist/services/FilesystemService.js +391 -0
  73. package/dist/services/FilesystemService.js.map +1 -0
  74. package/dist/services/index.d.ts +2 -0
  75. package/dist/services/index.d.ts.map +1 -0
  76. package/dist/services/index.js +7 -0
  77. package/dist/services/index.js.map +1 -0
  78. package/dist/types/file-system.d.ts +7 -0
  79. package/dist/types/file-system.d.ts.map +1 -0
  80. package/dist/types/file-system.js +7 -0
  81. package/dist/types/file-system.js.map +1 -0
  82. package/dist/types/index.d.ts +4 -0
  83. package/dist/types/index.d.ts.map +1 -0
  84. package/dist/types/index.js +3 -0
  85. package/dist/types/index.js.map +1 -0
  86. package/dist/types/layer-types.d.ts +187 -0
  87. package/dist/types/layer-types.d.ts.map +1 -0
  88. package/dist/types/layer-types.js +7 -0
  89. package/dist/types/layer-types.js.map +1 -0
  90. package/dist/types/version-control-layer.d.ts +53 -0
  91. package/dist/types/version-control-layer.d.ts.map +1 -0
  92. package/dist/types/version-control-layer.js +3 -0
  93. package/dist/types/version-control-layer.js.map +1 -0
  94. package/dist/types/workspace-boundaries.d.ts +17 -0
  95. package/dist/types/workspace-boundaries.d.ts.map +1 -0
  96. package/dist/types/workspace-boundaries.js +7 -0
  97. package/dist/types/workspace-boundaries.js.map +1 -0
  98. package/package.json +42 -0
  99. package/src/index.ts +62 -0
  100. package/src/modules/DependencyLayerModule.ts +329 -0
  101. package/src/modules/FileSystemModule.ts +65 -0
  102. package/src/modules/FileTypeLayerModule.ts +199 -0
  103. package/src/modules/FrameworkLayerModule.ts +437 -0
  104. package/src/modules/PackageLayerModule.ts +979 -0
  105. package/src/modules/TypeExtractionModule.test.ts +340 -0
  106. package/src/modules/TypeExtractionModule.ts +180 -0
  107. package/src/modules/VersionControlLayerModule.ts +31 -0
  108. package/src/modules/__fixtures__/typescript-packages/complex-types/package.json +6 -0
  109. package/src/modules/__fixtures__/typescript-packages/complex-types/src/index.ts +6 -0
  110. package/src/modules/__fixtures__/typescript-packages/complex-types/src/models/category.ts +15 -0
  111. package/src/modules/__fixtures__/typescript-packages/complex-types/src/models/product.ts +48 -0
  112. package/src/modules/__fixtures__/typescript-packages/javascript-only/index.js +18 -0
  113. package/src/modules/__fixtures__/typescript-packages/javascript-only/package.json +5 -0
  114. package/src/modules/__fixtures__/typescript-packages/simple-types/index.ts +53 -0
  115. package/src/modules/__fixtures__/typescript-packages/simple-types/package.json +6 -0
  116. package/src/modules/extractors/README.md +55 -0
  117. package/src/modules/extractors/TypeScriptExtractor.ts +409 -0
  118. package/src/modules/index.ts +13 -0
  119. package/src/providers/GitVersionControlProvider.ts +500 -0
  120. package/src/providers/PackageManagerApiProvider.ts +108 -0
  121. package/src/providers/README.md +88 -0
  122. package/src/providers/index.ts +17 -0
  123. package/src/services/FilesystemService.ts +530 -0
  124. package/src/services/index.ts +2 -0
  125. package/src/types/file-system.ts +11 -0
  126. package/src/types/index.ts +24 -0
  127. package/src/types/layer-types.ts +264 -0
  128. package/src/types/version-control-layer.ts +87 -0
  129. package/src/types/workspace-boundaries.ts +17 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * User interface for testing
3
+ * @description Represents a user in the system
4
+ */
5
+ export interface User {
6
+ id: string;
7
+ name: string;
8
+ email: string;
9
+ age?: number;
10
+ }
11
+
12
+ /**
13
+ * Status type for testing union types
14
+ */
15
+ export type Status = 'active' | 'inactive' | 'pending';
16
+
17
+ /**
18
+ * UserProfile class for testing class extraction
19
+ */
20
+ export class UserProfile {
21
+ constructor(
22
+ public user: User,
23
+ public status: Status,
24
+ ) {}
25
+
26
+ getDisplayName(): string {
27
+ return this.user.name;
28
+ }
29
+
30
+ isActive(): boolean {
31
+ return this.status === 'active';
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Action enum for testing enum extraction
37
+ */
38
+ export enum Action {
39
+ CREATE = 'create',
40
+ UPDATE = 'update',
41
+ DELETE = 'delete',
42
+ READ = 'read',
43
+ }
44
+
45
+ /**
46
+ * Utility function for testing function extraction
47
+ */
48
+ export function formatUser(user: User): string {
49
+ return `${user.name} <${user.email}>`;
50
+ }
51
+
52
+ // Default export
53
+ export default UserProfile;
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "simple-types-test",
3
+ "version": "1.0.0",
4
+ "main": "index.ts",
5
+ "types": "index.ts"
6
+ }
@@ -0,0 +1,55 @@
1
+ # Type Extractors
2
+
3
+ This directory contains language-specific type extractors that implement the `TypeExtractor` interface.
4
+
5
+ ## Current Extractors
6
+
7
+ ### TypeScriptExtractor
8
+
9
+ - **Language**: TypeScript/JavaScript
10
+ - **File Extensions**: `.ts`, `.tsx`
11
+ - **Features**:
12
+ - Extracts interfaces, types, classes, enums, functions
13
+ - Supports JSDoc comments
14
+ - Handles default and named exports
15
+ - Generates TypeScript definition files
16
+
17
+ ## Adding New Extractors
18
+
19
+ To add support for a new language, implement the `TypeExtractor` interface:
20
+
21
+ ```typescript
22
+ import { TypeExtractor, PackageTypes } from '../../types/layer-types';
23
+
24
+ export class PythonExtractor implements TypeExtractor {
25
+ name = 'Python';
26
+
27
+ canHandle(packagePath: string, fileExtensions: string[]): boolean {
28
+ return fileExtensions.includes('.py');
29
+ }
30
+
31
+ async extractTypes(packagePath: string, options?: any): Promise<PackageTypes> {
32
+ // Use Python AST or tools like mypy to extract type information
33
+ // Return PackageTypes with extracted Python types
34
+ }
35
+
36
+ async generateDefinitionFile?(packageTypes: PackageTypes): Promise<string> {
37
+ // Generate .pyi stub files
38
+ }
39
+ }
40
+ ```
41
+
42
+ Then register it with the TypeExtractionModule:
43
+
44
+ ```typescript
45
+ const extractor = new TypeExtractionModule();
46
+ extractor.registerExtractor(new PythonExtractor());
47
+ ```
48
+
49
+ ## Architecture Benefits
50
+
51
+ - **Language Agnostic**: Core system works with any language
52
+ - **Extensible**: Easy to add new languages
53
+ - **Consistent API**: All extractors provide the same interface
54
+ - **Registry Pattern**: Dynamic extractor discovery and registration
55
+ - **Future-Proof**: Ready for Go, Java, C#, etc.
@@ -0,0 +1,409 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ import * as ts from 'typescript';
5
+
6
+ import { TypeExtractor, ExtractedType, PackageTypes } from '../../types/layer-types';
7
+
8
+ export interface TypeScriptExtractionOptions {
9
+ includeTests?: boolean;
10
+ includeInternal?: boolean;
11
+ }
12
+
13
+ export class TypeScriptExtractor implements TypeExtractor {
14
+ name = 'TypeScript';
15
+
16
+ canHandle(packagePath: string, fileExtensions: string[]): boolean {
17
+ // Check if package contains TypeScript files
18
+ return fileExtensions.some(ext => ['.ts', '.tsx'].includes(ext));
19
+ }
20
+
21
+ async extractTypes(
22
+ packagePath: string,
23
+ options: TypeScriptExtractionOptions = {},
24
+ ): Promise<PackageTypes> {
25
+ console.log(`[TypeScriptExtractor] Extracting types from package path: ${packagePath}`);
26
+
27
+ // Verify package path exists
28
+ if (!fs.existsSync(packagePath)) {
29
+ throw new Error(`Package path does not exist: ${packagePath}`);
30
+ }
31
+
32
+ // Read package.json to get package name
33
+ const packageJsonPath = path.join(packagePath, 'package.json');
34
+ let packageName = path.basename(packagePath);
35
+
36
+ try {
37
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
38
+ packageName = packageJson.name || packageName;
39
+ } catch (error) {
40
+ console.log(`[TypeScriptExtractor] Could not read package.json: ${error}`);
41
+ }
42
+
43
+ // Find all TypeScript files in the package
44
+ const tsFiles = this.findTypeScriptFiles(packagePath, options);
45
+
46
+ if (tsFiles.length === 0) {
47
+ return {
48
+ packagePath,
49
+ packageName,
50
+ types: [],
51
+ exports: { named: [] },
52
+ };
53
+ }
54
+
55
+ // Create a TypeScript program
56
+ const compilerOptions: ts.CompilerOptions = {
57
+ target: ts.ScriptTarget.ES2020,
58
+ module: ts.ModuleKind.CommonJS,
59
+ lib: ['es2020'],
60
+ declaration: true,
61
+ emitDeclarationOnly: true,
62
+ skipLibCheck: true,
63
+ allowJs: false,
64
+ resolveJsonModule: true,
65
+ esModuleInterop: true,
66
+ strict: true,
67
+ };
68
+
69
+ const program = ts.createProgram(tsFiles, compilerOptions);
70
+ const checker = program.getTypeChecker();
71
+ const extractedTypes: ExtractedType[] = [];
72
+ const exportedNames = new Set<string>();
73
+ const defaultExport: { value?: string } = {};
74
+
75
+ // Process each source file
76
+ for (const sourceFile of program.getSourceFiles()) {
77
+ if (sourceFile.isDeclarationFile) continue;
78
+ if (!sourceFile.fileName.startsWith(packagePath)) continue;
79
+
80
+ // Visit each node in the source file
81
+ ts.forEachChild(sourceFile, node => {
82
+ this.visitNode(
83
+ node,
84
+ sourceFile,
85
+ checker,
86
+ extractedTypes,
87
+ exportedNames,
88
+ defaultExport,
89
+ packagePath,
90
+ );
91
+ });
92
+ }
93
+
94
+ // Sort types by kind and name
95
+ extractedTypes.sort((a, b) => {
96
+ const kindOrder = ['interface', 'type', 'class', 'enum', 'function'];
97
+ const aOrder = kindOrder.indexOf(a.kind);
98
+ const bOrder = kindOrder.indexOf(b.kind);
99
+ if (aOrder !== bOrder) return aOrder - bOrder;
100
+ return a.name.localeCompare(b.name);
101
+ });
102
+
103
+ return {
104
+ packagePath,
105
+ packageName,
106
+ types: extractedTypes,
107
+ exports: {
108
+ named: Array.from(exportedNames),
109
+ default: defaultExport.value,
110
+ },
111
+ };
112
+ }
113
+
114
+ async generateDefinitionFile(packageTypes: PackageTypes): Promise<string> {
115
+ const lines: string[] = [];
116
+
117
+ // Add header
118
+ lines.push(`// Type definitions for ${packageTypes.packageName}`);
119
+ lines.push(`// Generated from: ${packageTypes.packagePath}`);
120
+ lines.push(`// Generated on: ${new Date().toISOString()}`);
121
+ lines.push('');
122
+
123
+ // Group types by kind
124
+ const typesByKind = packageTypes.types.reduce(
125
+ (acc, type) => {
126
+ if (!acc[type.kind]) acc[type.kind] = [];
127
+ acc[type.kind].push(type);
128
+ return acc;
129
+ },
130
+ {} as Record<string, ExtractedType[]>,
131
+ );
132
+
133
+ // Add types in order
134
+ const kinds = ['interface', 'type', 'class', 'enum', 'function'] as const;
135
+ for (const kind of kinds) {
136
+ const types = typesByKind[kind];
137
+ if (!types || types.length === 0) continue;
138
+
139
+ lines.push(`// ${kind.charAt(0).toUpperCase() + kind.slice(1)}s`);
140
+ lines.push('');
141
+
142
+ for (const type of types) {
143
+ if (type.jsDoc) {
144
+ lines.push(`/** ${type.jsDoc} */`);
145
+ }
146
+ if (type.isExported) {
147
+ // Remove existing 'export' keyword if present to avoid duplication
148
+ const cleanText = type.text.replace(/^export\s+/, '');
149
+ lines.push(`export ${cleanText}`);
150
+ } else {
151
+ lines.push(type.text);
152
+ }
153
+ lines.push('');
154
+ }
155
+ }
156
+
157
+ return lines.join('\n');
158
+ }
159
+
160
+ private findTypeScriptFiles(dir: string, options: TypeScriptExtractionOptions = {}): string[] {
161
+ const files: string[] = [];
162
+
163
+ const walk = (currentDir: string) => {
164
+ try {
165
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
166
+
167
+ for (const entry of entries) {
168
+ const fullPath = path.join(currentDir, entry.name);
169
+
170
+ if (entry.isDirectory()) {
171
+ // Skip node_modules and hidden directories
172
+ if (entry.name !== 'node_modules' && !entry.name.startsWith('.')) {
173
+ walk(fullPath);
174
+ }
175
+ } else if (entry.isFile()) {
176
+ if (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx')) {
177
+ // Skip declaration files
178
+ if (entry.name.endsWith('.d.ts')) {
179
+ continue;
180
+ }
181
+
182
+ // Skip test files unless explicitly included
183
+ if (!options.includeTests) {
184
+ if (entry.name.includes('.test.') || entry.name.includes('.spec.')) {
185
+ continue;
186
+ }
187
+ }
188
+
189
+ files.push(fullPath);
190
+ }
191
+ }
192
+ }
193
+ } catch (error) {
194
+ console.error(`[TypeScriptExtractor] Error reading directory ${currentDir}:`, error);
195
+ }
196
+ };
197
+
198
+ walk(dir);
199
+ return files;
200
+ }
201
+
202
+ private visitNode(
203
+ node: ts.Node,
204
+ sourceFile: ts.SourceFile,
205
+ checker: ts.TypeChecker,
206
+ extractedTypes: ExtractedType[],
207
+ exportedNames: Set<string>,
208
+ defaultExport: { value?: string },
209
+ packagePath: string,
210
+ ) {
211
+ const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
212
+ const isExported = modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) || false;
213
+ const isDefaultExport = modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword) || false;
214
+
215
+ // Extract JSDoc comments
216
+ const jsDoc = this.getJSDocComment(node, sourceFile);
217
+
218
+ // Get relative file path from package root
219
+ const getRelativeFileName = (): string => {
220
+ const relativePath = path.relative(packagePath, sourceFile.fileName);
221
+ return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
222
+ };
223
+
224
+ if (ts.isInterfaceDeclaration(node)) {
225
+ const name = node.name?.text || 'Anonymous';
226
+ const text = this.getNodeText(node, sourceFile);
227
+
228
+ // Only extract exported types
229
+ if (isExported) {
230
+ extractedTypes.push({
231
+ name,
232
+ kind: 'interface',
233
+ text,
234
+ fileName: getRelativeFileName(),
235
+ isExported,
236
+ jsDoc,
237
+ });
238
+
239
+ exportedNames.add(name);
240
+ }
241
+
242
+ if (isDefaultExport) {
243
+ defaultExport.value = name;
244
+ }
245
+ } else if (ts.isTypeAliasDeclaration(node)) {
246
+ const name = node.name?.text || 'Anonymous';
247
+ const text = this.getNodeText(node, sourceFile);
248
+
249
+ if (isExported) {
250
+ extractedTypes.push({
251
+ name,
252
+ kind: 'type',
253
+ text,
254
+ fileName: getRelativeFileName(),
255
+ isExported,
256
+ jsDoc,
257
+ });
258
+
259
+ exportedNames.add(name);
260
+ }
261
+
262
+ if (isDefaultExport) {
263
+ defaultExport.value = name;
264
+ }
265
+ } else if (ts.isClassDeclaration(node)) {
266
+ const name = node.name?.text || 'Anonymous';
267
+ const text = this.getClassSignature(node, sourceFile, checker);
268
+
269
+ if (isExported) {
270
+ extractedTypes.push({
271
+ name,
272
+ kind: 'class',
273
+ text,
274
+ fileName: getRelativeFileName(),
275
+ isExported,
276
+ jsDoc,
277
+ });
278
+
279
+ exportedNames.add(name);
280
+ }
281
+
282
+ if (isDefaultExport) {
283
+ defaultExport.value = name;
284
+ }
285
+ } else if (ts.isEnumDeclaration(node)) {
286
+ const name = node.name?.text || 'Anonymous';
287
+ const text = this.getNodeText(node, sourceFile);
288
+
289
+ if (isExported) {
290
+ extractedTypes.push({
291
+ name,
292
+ kind: 'enum',
293
+ text,
294
+ fileName: getRelativeFileName(),
295
+ isExported,
296
+ jsDoc,
297
+ });
298
+
299
+ exportedNames.add(name);
300
+ }
301
+
302
+ if (isDefaultExport) {
303
+ defaultExport.value = name;
304
+ }
305
+ } else if (ts.isFunctionDeclaration(node) && node.name) {
306
+ const name = node.name.text;
307
+ const text = this.getFunctionSignature(node, sourceFile, checker);
308
+
309
+ if (isExported) {
310
+ extractedTypes.push({
311
+ name,
312
+ kind: 'function',
313
+ text,
314
+ fileName: getRelativeFileName(),
315
+ isExported,
316
+ jsDoc,
317
+ });
318
+
319
+ exportedNames.add(name);
320
+ }
321
+
322
+ if (isDefaultExport) {
323
+ defaultExport.value = name;
324
+ }
325
+ }
326
+
327
+ // Handle export default statements separately
328
+ if (ts.isExportAssignment(node) && !node.isExportEquals) {
329
+ // This is an "export default" statement
330
+ if (ts.isIdentifier(node.expression)) {
331
+ defaultExport.value = node.expression.text;
332
+ }
333
+ }
334
+
335
+ // Continue visiting child nodes
336
+ ts.forEachChild(node, child => {
337
+ this.visitNode(
338
+ child,
339
+ sourceFile,
340
+ checker,
341
+ extractedTypes,
342
+ exportedNames,
343
+ defaultExport,
344
+ packagePath,
345
+ );
346
+ });
347
+ }
348
+
349
+ private getNodeText(node: ts.Node, sourceFile: ts.SourceFile): string {
350
+ return node.getText(sourceFile);
351
+ }
352
+
353
+ private getJSDocComment(node: ts.Node, _sourceFile: ts.SourceFile): string | undefined {
354
+ // Get the full JSDoc comments including the main comment and tags
355
+ const jsDocComments = ts.getJSDocCommentsAndTags(node);
356
+ if (jsDocComments.length === 0) return undefined;
357
+
358
+ const comments: string[] = [];
359
+
360
+ jsDocComments.forEach(comment => {
361
+ if (ts.isJSDoc(comment)) {
362
+ // Get the main comment text
363
+ if (comment.comment) {
364
+ if (typeof comment.comment === 'string') {
365
+ comments.push(comment.comment);
366
+ } else if (Array.isArray(comment.comment)) {
367
+ comments.push(comment.comment.map(c => c.text).join(''));
368
+ }
369
+ }
370
+
371
+ // Get text from tags (like @description)
372
+ comment.tags?.forEach(tag => {
373
+ if (tag.comment) {
374
+ if (typeof tag.comment === 'string') {
375
+ comments.push(tag.comment);
376
+ } else if (Array.isArray(tag.comment)) {
377
+ comments.push(tag.comment.map(c => c.text).join(''));
378
+ }
379
+ }
380
+ });
381
+ }
382
+ });
383
+
384
+ return comments.length > 0 ? comments.join('\n') : undefined;
385
+ }
386
+
387
+ private getClassSignature(
388
+ node: ts.ClassDeclaration,
389
+ sourceFile: ts.SourceFile,
390
+ _checker: ts.TypeChecker,
391
+ ): string {
392
+ // For now, return the full class declaration
393
+ // In the future, we could extract just the public API
394
+ return this.getNodeText(node, sourceFile);
395
+ }
396
+
397
+ private getFunctionSignature(
398
+ node: ts.FunctionDeclaration,
399
+ sourceFile: ts.SourceFile,
400
+ _checker: ts.TypeChecker,
401
+ ): string {
402
+ // Get just the function signature without the body
403
+ const signature = node.name?.text || 'anonymous';
404
+ const params = node.parameters.map(p => p.getText(sourceFile)).join(', ');
405
+ const returnType = node.type ? `: ${node.type.getText(sourceFile)}` : '';
406
+
407
+ return `function ${signature}(${params})${returnType}`;
408
+ }
409
+ }
@@ -0,0 +1,13 @@
1
+ // Export layer modules
2
+ export { FileTypeLayerModule } from './FileTypeLayerModule';
3
+ export type { FileTypeInfo } from './FileTypeLayerModule';
4
+ export { PackageLayerModule } from './PackageLayerModule';
5
+ export { VersionControlLayerFactory } from './VersionControlLayerModule';
6
+ export { DependencyLayerModule } from './DependencyLayerModule';
7
+ export { FrameworkLayerModule } from './FrameworkLayerModule';
8
+ export { FileSystemModule } from './FileSystemModule';
9
+ export type { FileSystemModuleConfig, FileSystemLoadResult } from './FileSystemModule';
10
+ export { TypeExtractionModule } from './TypeExtractionModule';
11
+ export type { TypeExtractionOptions } from './TypeExtractionModule';
12
+ export { TypeScriptExtractor } from './extractors/TypeScriptExtractor';
13
+ export type { TypeScriptExtractionOptions } from './extractors/TypeScriptExtractor';