@ai-coders/context 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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +658 -0
  3. package/dist/generators/agentGenerator.d.ts +23 -0
  4. package/dist/generators/agentGenerator.d.ts.map +1 -0
  5. package/dist/generators/agentGenerator.js +357 -0
  6. package/dist/generators/agentGenerator.js.map +1 -0
  7. package/dist/generators/documentationGenerator.d.ts +40 -0
  8. package/dist/generators/documentationGenerator.d.ts.map +1 -0
  9. package/dist/generators/documentationGenerator.js +786 -0
  10. package/dist/generators/documentationGenerator.js.map +1 -0
  11. package/dist/generators/incrementalDocumentationGenerator.d.ts +33 -0
  12. package/dist/generators/incrementalDocumentationGenerator.d.ts.map +1 -0
  13. package/dist/generators/incrementalDocumentationGenerator.js +400 -0
  14. package/dist/generators/incrementalDocumentationGenerator.js.map +1 -0
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +559 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/services/anthropicClient.d.ts +12 -0
  20. package/dist/services/anthropicClient.d.ts.map +1 -0
  21. package/dist/services/anthropicClient.js +98 -0
  22. package/dist/services/anthropicClient.js.map +1 -0
  23. package/dist/services/baseLLMClient.d.ts +12 -0
  24. package/dist/services/baseLLMClient.d.ts.map +1 -0
  25. package/dist/services/baseLLMClient.js +41 -0
  26. package/dist/services/baseLLMClient.js.map +1 -0
  27. package/dist/services/changeAnalyzer.d.ts +44 -0
  28. package/dist/services/changeAnalyzer.d.ts.map +1 -0
  29. package/dist/services/changeAnalyzer.js +344 -0
  30. package/dist/services/changeAnalyzer.js.map +1 -0
  31. package/dist/services/geminiClient.d.ts +12 -0
  32. package/dist/services/geminiClient.d.ts.map +1 -0
  33. package/dist/services/geminiClient.js +96 -0
  34. package/dist/services/geminiClient.js.map +1 -0
  35. package/dist/services/grokClient.d.ts +12 -0
  36. package/dist/services/grokClient.d.ts.map +1 -0
  37. package/dist/services/grokClient.js +101 -0
  38. package/dist/services/grokClient.js.map +1 -0
  39. package/dist/services/llmClientFactory.d.ts +14 -0
  40. package/dist/services/llmClientFactory.d.ts.map +1 -0
  41. package/dist/services/llmClientFactory.js +109 -0
  42. package/dist/services/llmClientFactory.js.map +1 -0
  43. package/dist/services/openRouterClient.d.ts +12 -0
  44. package/dist/services/openRouterClient.d.ts.map +1 -0
  45. package/dist/services/openRouterClient.js +96 -0
  46. package/dist/services/openRouterClient.js.map +1 -0
  47. package/dist/services/openaiClient.d.ts +12 -0
  48. package/dist/services/openaiClient.d.ts.map +1 -0
  49. package/dist/services/openaiClient.js +98 -0
  50. package/dist/services/openaiClient.js.map +1 -0
  51. package/dist/types.d.ts +60 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +3 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/utils/cliUI.d.ts +25 -0
  56. package/dist/utils/cliUI.d.ts.map +1 -0
  57. package/dist/utils/cliUI.js +236 -0
  58. package/dist/utils/cliUI.js.map +1 -0
  59. package/dist/utils/fileMapper.d.ts +11 -0
  60. package/dist/utils/fileMapper.d.ts.map +1 -0
  61. package/dist/utils/fileMapper.js +125 -0
  62. package/dist/utils/fileMapper.js.map +1 -0
  63. package/dist/utils/gitService.d.ts +50 -0
  64. package/dist/utils/gitService.d.ts.map +1 -0
  65. package/dist/utils/gitService.js +470 -0
  66. package/dist/utils/gitService.js.map +1 -0
  67. package/dist/utils/interactiveMode.d.ts +16 -0
  68. package/dist/utils/interactiveMode.d.ts.map +1 -0
  69. package/dist/utils/interactiveMode.js +432 -0
  70. package/dist/utils/interactiveMode.js.map +1 -0
  71. package/dist/utils/pricing.d.ts +14 -0
  72. package/dist/utils/pricing.d.ts.map +1 -0
  73. package/dist/utils/pricing.js +115 -0
  74. package/dist/utils/pricing.js.map +1 -0
  75. package/dist/utils/tokenEstimator.d.ts +27 -0
  76. package/dist/utils/tokenEstimator.d.ts.map +1 -0
  77. package/dist/utils/tokenEstimator.js +198 -0
  78. package/dist/utils/tokenEstimator.js.map +1 -0
  79. package/package.json +73 -0
@@ -0,0 +1,786 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DocumentationGenerator = void 0;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ class DocumentationGenerator {
44
+ constructor(fileMapper, llmClient) {
45
+ this.fileMapper = fileMapper;
46
+ this.llmClient = llmClient;
47
+ }
48
+ async generateDocumentation(repoStructure, outputDir, verbose = false) {
49
+ const docsDir = path.join(outputDir, 'docs');
50
+ await fs.ensureDir(docsDir);
51
+ if (verbose) {
52
+ console.log(chalk_1.default.blue(`📚 Generating documentation in: ${docsDir}`));
53
+ }
54
+ // Generate main documentation index
55
+ await this.generateMainIndex(repoStructure, docsDir, verbose);
56
+ // Generate overview documentation
57
+ await this.generateOverview(repoStructure, docsDir, verbose);
58
+ // Generate architecture documentation
59
+ await this.generateArchitectureDoc(repoStructure, docsDir, verbose);
60
+ // Generate module-based documentation
61
+ await this.generateModuleDocumentation(repoStructure, docsDir, verbose);
62
+ // Generate API reference
63
+ await this.generateAPIReference(repoStructure, docsDir, verbose);
64
+ // Generate configuration guide
65
+ await this.generateConfigurationGuide(repoStructure, docsDir, verbose);
66
+ // Generate development guide
67
+ await this.generateDevelopmentGuide(repoStructure, docsDir, verbose);
68
+ // Generate deployment guide
69
+ await this.generateDeploymentGuide(repoStructure, docsDir, verbose);
70
+ // Generate troubleshooting guide
71
+ await this.generateTroubleshootingGuide(repoStructure, docsDir, verbose);
72
+ }
73
+ async generateMainIndex(repoStructure, docsDir, verbose) {
74
+ const fileName = 'README.md';
75
+ if (verbose) {
76
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
77
+ }
78
+ const indexContent = `# Documentation Index
79
+
80
+ Welcome to the project documentation. This guide is organized into the following sections:
81
+
82
+ ## 📚 Documentation Structure
83
+
84
+ ### [Overview](./overview.md)
85
+ High-level project overview, statistics, and key components.
86
+
87
+ ### [Architecture](./architecture.md)
88
+ System architecture, design patterns, and technical decisions.
89
+
90
+ ### [Modules](./modules/)
91
+ Detailed documentation for each module/component:
92
+ ${this.getModuleGroups(repoStructure).map(group => `- [${group.name}](./modules/${this.slugify(group.name)}.md) - ${group.description}`).join('\n')}
93
+
94
+ ### [API Reference](./api-reference.md)
95
+ Complete API documentation for all public interfaces.
96
+
97
+ ### [Configuration](./configuration.md)
98
+ Configuration options, environment variables, and setup guides.
99
+
100
+ ## 🚀 Quick Links
101
+
102
+ - [Getting Started](#getting-started)
103
+ - [Project Structure](./overview.md#project-structure)
104
+ - [Key Components](./architecture.md#key-components)
105
+ - [Contributing Guidelines](../CONTRIBUTING.md)
106
+
107
+ ---
108
+ *Generated by AI Coders Context*
109
+ *Last updated: ${new Date().toISOString()}*
110
+ `;
111
+ const indexPath = path.join(docsDir, fileName);
112
+ await fs.writeFile(indexPath, indexContent);
113
+ if (verbose) {
114
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
115
+ }
116
+ }
117
+ async generateOverview(repoStructure, docsDir, verbose) {
118
+ const fileName = 'overview.md';
119
+ if (verbose) {
120
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
121
+ }
122
+ const overview = await this.createEnhancedProjectOverview(repoStructure);
123
+ const overviewPath = path.join(docsDir, fileName);
124
+ await fs.writeFile(overviewPath, overview);
125
+ if (verbose) {
126
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
127
+ }
128
+ }
129
+ async generateArchitectureDoc(repoStructure, docsDir, verbose) {
130
+ const fileName = 'architecture.md';
131
+ if (verbose) {
132
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
133
+ }
134
+ const architecture = await this.createArchitectureDocumentation(repoStructure);
135
+ const archPath = path.join(docsDir, fileName);
136
+ await fs.writeFile(archPath, architecture);
137
+ if (verbose) {
138
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
139
+ }
140
+ }
141
+ async generateModuleDocumentation(repoStructure, docsDir, verbose) {
142
+ const modulesDir = path.join(docsDir, 'modules');
143
+ await fs.ensureDir(modulesDir);
144
+ const moduleGroups = this.getModuleGroups(repoStructure);
145
+ if (verbose) {
146
+ console.log(chalk_1.default.yellow(`📦 Generating documentation for ${moduleGroups.length} modules...`));
147
+ }
148
+ for (const module of moduleGroups) {
149
+ try {
150
+ const moduleDoc = await this.createModuleDocumentation(module, repoStructure);
151
+ const modulePath = path.join(modulesDir, `${this.slugify(module.name)}.md`);
152
+ await fs.writeFile(modulePath, moduleDoc);
153
+ if (verbose) {
154
+ console.log(chalk_1.default.green(`✅ Module documentation generated: ${module.name}`));
155
+ }
156
+ }
157
+ catch (error) {
158
+ if (verbose) {
159
+ console.log(chalk_1.default.red(`❌ Error documenting module ${module.name}: ${error}`));
160
+ }
161
+ }
162
+ }
163
+ }
164
+ async generateAPIReference(repoStructure, docsDir, verbose) {
165
+ if (verbose) {
166
+ console.log(chalk_1.default.yellow('🔌 Generating API reference...'));
167
+ }
168
+ const apiRef = await this.createAPIReference(repoStructure);
169
+ const apiPath = path.join(docsDir, 'api-reference.md');
170
+ await fs.writeFile(apiPath, apiRef);
171
+ if (verbose) {
172
+ console.log(chalk_1.default.green(`✅ API reference saved: ${apiPath}`));
173
+ }
174
+ }
175
+ async generateConfigurationGuide(repoStructure, docsDir, verbose) {
176
+ if (verbose) {
177
+ console.log(chalk_1.default.yellow('⚙️ Generating configuration guide...'));
178
+ }
179
+ const configGuide = await this.createConfigurationGuide(repoStructure);
180
+ const configPath = path.join(docsDir, 'configuration.md');
181
+ await fs.writeFile(configPath, configGuide);
182
+ if (verbose) {
183
+ console.log(chalk_1.default.green(`✅ Configuration guide saved: ${configPath}`));
184
+ }
185
+ }
186
+ getModuleGroups(repoStructure) {
187
+ const groups = new Map();
188
+ // Group files by their top-level directory or logical module
189
+ repoStructure.files.forEach(file => {
190
+ if (!this.fileMapper.isTextFile(file.path))
191
+ return;
192
+ const parts = file.relativePath.split(path.sep);
193
+ let groupName = 'Root Files';
194
+ if (parts.length > 1) {
195
+ groupName = parts[0];
196
+ // Special handling for src files
197
+ if (groupName === 'src' && parts.length > 2) {
198
+ groupName = `${parts[1]}`;
199
+ }
200
+ }
201
+ if (!groups.has(groupName)) {
202
+ groups.set(groupName, []);
203
+ }
204
+ groups.get(groupName).push(file);
205
+ });
206
+ // Convert to ModuleGroup array with descriptions
207
+ return Array.from(groups.entries()).map(([name, files]) => ({
208
+ name: this.formatModuleName(name),
209
+ description: this.getModuleDescription(name, files),
210
+ files
211
+ })).sort((a, b) => a.name.localeCompare(b.name));
212
+ }
213
+ formatModuleName(name) {
214
+ return name
215
+ .split(/[-_]/)
216
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
217
+ .join(' ');
218
+ }
219
+ getModuleDescription(name, files) {
220
+ const descriptions = {
221
+ 'generators': 'Code generation utilities for documentation and agents',
222
+ 'services': 'External service integrations and API clients',
223
+ 'utils': 'Utility functions and helper modules',
224
+ 'types': 'TypeScript type definitions and interfaces',
225
+ 'Root Files': 'Main configuration and entry point files'
226
+ };
227
+ return descriptions[name] || `${this.formatModuleName(name)} module with ${files.length} files`;
228
+ }
229
+ async createModuleDocumentation(module, repoStructure) {
230
+ const fileContents = [];
231
+ for (const file of module.files.slice(0, 10)) { // Limit to prevent too large requests
232
+ const content = await this.fileMapper.readFileContent(file.path);
233
+ fileContents.push(`File: ${file.relativePath}\n${content.substring(0, 1000)}...`);
234
+ }
235
+ const moduleContext = `Module: ${module.name}
236
+ Description: ${module.description}
237
+ Files: ${module.files.map(f => f.relativePath).join(', ')}
238
+
239
+ Sample content from module files:
240
+ ${fileContents.join('\n\n---\n\n')}`;
241
+ const documentation = await this.llmClient.generateText(`Generate comprehensive documentation for this module. Include:
242
+ 1. Module overview and purpose
243
+ 2. Key components and their responsibilities
244
+ 3. Public APIs and interfaces
245
+ 4. Usage examples
246
+ 5. Dependencies and relationships
247
+
248
+ Module context:
249
+ ${moduleContext}`, 'You are a technical documentation expert. Create clear, well-structured module documentation.');
250
+ return `# ${module.name}
251
+
252
+ ${documentation}
253
+
254
+ ## Files in this module
255
+
256
+ ${module.files.map(file => `- \`${file.relativePath}\` - ${this.formatBytes(file.size)}`).join('\n')}
257
+
258
+ ---
259
+ *Generated by AI Coders Context*
260
+ `;
261
+ }
262
+ async createEnhancedProjectOverview(repoStructure) {
263
+ const { files, directories, totalFiles, totalSize } = repoStructure;
264
+ const extensions = new Map();
265
+ files.forEach(file => {
266
+ const ext = file.extension || 'no-extension';
267
+ extensions.set(ext, (extensions.get(ext) || 0) + 1);
268
+ });
269
+ const topExtensions = Array.from(extensions.entries())
270
+ .sort((a, b) => b[1] - a[1])
271
+ .slice(0, 10);
272
+ // Try to identify project type
273
+ const projectType = this.identifyProjectType(repoStructure);
274
+ const techStack = this.identifyTechStack(repoStructure);
275
+ return `# Project Overview
276
+
277
+ ## Project Information
278
+ - **Type**: ${projectType}
279
+ - **Technology Stack**: ${techStack.join(', ')}
280
+ - **Total Files**: ${totalFiles}
281
+ - **Total Size**: ${this.formatBytes(totalSize)}
282
+
283
+ ## Project Structure
284
+
285
+ ### Directory Overview
286
+ \`\`\`
287
+ ${this.createSimplifiedTree(repoStructure)}
288
+ \`\`\`
289
+
290
+ ### File Distribution
291
+ ${topExtensions.map(([ext, count]) => `- **${ext}**: ${count} files (${((count / totalFiles) * 100).toFixed(1)}%)`).join('\n')}
292
+
293
+ ## Key Files
294
+ ${this.identifyKeyFiles(repoStructure).map(f => `- \`${f.relativePath}\` - ${f.description}`).join('\n')}
295
+
296
+ ## Development Setup
297
+
298
+ Refer to the [Configuration Guide](./configuration.md) for detailed setup instructions.
299
+
300
+ ---
301
+ *Generated by AI Coders Context*
302
+ `;
303
+ }
304
+ async createArchitectureDocumentation(repoStructure) {
305
+ const modules = this.getModuleGroups(repoStructure);
306
+ const techStack = this.identifyTechStack(repoStructure);
307
+ return `# Architecture Documentation
308
+
309
+ ## System Overview
310
+
311
+ This document describes the high-level architecture of the project.
312
+
313
+ ## Technology Stack
314
+
315
+ ${techStack.map(tech => `- **${tech}**`).join('\n')}
316
+
317
+ ## Component Architecture
318
+
319
+ ### Core Modules
320
+
321
+ ${modules.map(module => `#### ${module.name}
322
+ - **Purpose**: ${module.description}
323
+ - **Files**: ${module.files.length}
324
+ - **Key Responsibilities**: [To be analyzed]
325
+ `).join('\n')}
326
+
327
+ ## Design Patterns
328
+
329
+ Based on the codebase structure, the following patterns are identified:
330
+ - Command Pattern (CLI structure)
331
+ - Service Layer Pattern (services directory)
332
+ - Factory Pattern (generators)
333
+
334
+ ## Data Flow
335
+
336
+ 1. **Input Processing**: Command-line arguments are parsed
337
+ 2. **File Analysis**: Repository structure is mapped
338
+ 3. **Content Generation**: LLM-based documentation generation
339
+ 4. **Output Generation**: Structured documentation output
340
+
341
+ ## Dependencies
342
+
343
+ Analyze package.json for detailed dependency information.
344
+
345
+ ---
346
+ *Generated by AI Coders Context*
347
+ `;
348
+ }
349
+ async createAPIReference(repoStructure) {
350
+ const apiFiles = repoStructure.files.filter(f => f.relativePath.includes('types') ||
351
+ f.relativePath.includes('index') ||
352
+ f.relativePath.endsWith('.ts'));
353
+ return `# API Reference
354
+
355
+ ## Overview
356
+
357
+ This document provides a complete reference for all public APIs in the project.
358
+
359
+ ## Core APIs
360
+
361
+ ### CLI Commands
362
+
363
+ #### \`generate\`
364
+ Generate documentation and agent prompts for a repository.
365
+
366
+ **Usage:**
367
+ \`\`\`bash
368
+ ai-context generate <repo-path> [options]
369
+ \`\`\`
370
+
371
+ **Options:**
372
+ - \`-o, --output <dir>\`: Output directory
373
+ - \`-k, --api-key <key>\`: OpenRouter API key
374
+ - \`-m, --model <model>\`: LLM model to use
375
+ - \`--exclude <patterns...>\`: Patterns to exclude
376
+ - \`--include <patterns...>\`: Patterns to include
377
+
378
+ #### \`analyze\`
379
+ Analyze repository structure without generating content.
380
+
381
+ **Usage:**
382
+ \`\`\`bash
383
+ ai-context analyze <repo-path> [options]
384
+ \`\`\`
385
+
386
+ ## Module APIs
387
+
388
+ ${this.getModuleGroups(repoStructure).map(module => `### ${module.name}\nSee [${module.name} Module Documentation](./modules/${this.slugify(module.name)}.md)`).join('\n\n')}
389
+
390
+ ## Type Definitions
391
+
392
+ See the types module for detailed interface definitions.
393
+
394
+ ---
395
+ *Generated by AI Coders Context*
396
+ `;
397
+ }
398
+ async createConfigurationGuide(repoStructure) {
399
+ const configFiles = repoStructure.files.filter(f => f.relativePath.includes('config') ||
400
+ f.relativePath.includes('.json') ||
401
+ f.relativePath.includes('.env'));
402
+ return `# Configuration Guide
403
+
404
+ ## Environment Variables
405
+
406
+ ### Required Variables
407
+
408
+ - \`OPENROUTER_API_KEY\`: Your OpenRouter API key for LLM access
409
+
410
+ ### Optional Variables
411
+
412
+ - \`OPENROUTER_MODEL\`: Override default model (default: \`google/gemini-2.5-flash-preview-05-20\`)
413
+ - \`OPENROUTER_BASE_URL\`: Custom API endpoint (rarely needed)
414
+
415
+ ## Configuration Files
416
+
417
+ ${configFiles.map(f => `### ${f.relativePath}
418
+ Configuration file for ${this.getConfigDescription(f.relativePath)}`).join('\n\n')}
419
+
420
+ ## Setup Instructions
421
+
422
+ 1. **Clone the repository**
423
+ \`\`\`bash
424
+ git clone https://github.com/vinilana/ai-coders-context.git
425
+ cd ai-coders-context
426
+ \`\`\`
427
+
428
+ 2. **Install dependencies**
429
+ \`\`\`bash
430
+ npm install
431
+ \`\`\`
432
+
433
+ 3. **Configure environment**
434
+ \`\`\`bash
435
+ cp .env.example .env
436
+ # Edit .env with your API key
437
+ \`\`\`
438
+
439
+ 4. **Build the project**
440
+ \`\`\`bash
441
+ npm run build
442
+ \`\`\`
443
+
444
+ ## Advanced Configuration
445
+
446
+ ### Custom Model Selection
447
+
448
+ You can use any model available on OpenRouter:
449
+ - \`anthropic/claude-3-haiku\` - Fast and efficient
450
+ - \`anthropic/claude-3-sonnet\` - Balanced performance
451
+ - \`openai/gpt-4\` - High quality output
452
+ - \`google/gemini-2.5-flash-preview-05-20\` - Google's latest model
453
+
454
+ ### Output Customization
455
+
456
+ Control what gets generated:
457
+ - \`--docs-only\`: Generate only documentation
458
+ - \`--agents-only\`: Generate only agent prompts
459
+ - \`--exclude\`: Exclude specific file patterns
460
+ - \`--include\`: Include only specific patterns
461
+
462
+ ---
463
+ *Generated by AI Coders Context*
464
+ `;
465
+ }
466
+ identifyProjectType(repoStructure) {
467
+ const files = repoStructure.files.map(f => f.relativePath);
468
+ if (files.some(f => f === 'package.json')) {
469
+ if (files.some(f => f.includes('react') || f.includes('.jsx') || f.includes('.tsx'))) {
470
+ return 'React Application';
471
+ }
472
+ else if (files.some(f => f.includes('angular.json'))) {
473
+ return 'Angular Application';
474
+ }
475
+ else if (files.some(f => f.includes('vue'))) {
476
+ return 'Vue Application';
477
+ }
478
+ else if (files.some(f => f.includes('next.config'))) {
479
+ return 'Next.js Application';
480
+ }
481
+ return 'Node.js Project';
482
+ }
483
+ else if (files.some(f => f === 'requirements.txt' || f === 'setup.py')) {
484
+ return 'Python Project';
485
+ }
486
+ else if (files.some(f => f === 'pom.xml')) {
487
+ return 'Java Maven Project';
488
+ }
489
+ else if (files.some(f => f === 'build.gradle')) {
490
+ return 'Java Gradle Project';
491
+ }
492
+ return 'General Software Project';
493
+ }
494
+ identifyTechStack(repoStructure) {
495
+ const stack = [];
496
+ const files = repoStructure.files.map(f => f.relativePath);
497
+ // Languages
498
+ if (files.some(f => f.endsWith('.ts') || f.endsWith('.tsx')))
499
+ stack.push('TypeScript');
500
+ if (files.some(f => f.endsWith('.js') || f.endsWith('.jsx')))
501
+ stack.push('JavaScript');
502
+ if (files.some(f => f.endsWith('.py')))
503
+ stack.push('Python');
504
+ if (files.some(f => f.endsWith('.java')))
505
+ stack.push('Java');
506
+ // Frameworks
507
+ if (files.some(f => f === 'package.json'))
508
+ stack.push('Node.js');
509
+ if (files.some(f => f.includes('react')))
510
+ stack.push('React');
511
+ if (files.some(f => f.includes('vue')))
512
+ stack.push('Vue');
513
+ if (files.some(f => f.includes('angular')))
514
+ stack.push('Angular');
515
+ // Tools
516
+ if (files.some(f => f === 'tsconfig.json'))
517
+ stack.push('TypeScript Compiler');
518
+ if (files.some(f => f === 'jest.config.js'))
519
+ stack.push('Jest');
520
+ if (files.some(f => f === 'webpack.config.js'))
521
+ stack.push('Webpack');
522
+ return [...new Set(stack)];
523
+ }
524
+ identifyKeyFiles(repoStructure) {
525
+ const keyFiles = [];
526
+ repoStructure.files.forEach(file => {
527
+ const basename = path.basename(file.path);
528
+ const descriptions = {
529
+ 'package.json': 'Node.js project configuration and dependencies',
530
+ 'tsconfig.json': 'TypeScript compiler configuration',
531
+ 'README.md': 'Project documentation and setup guide',
532
+ '.gitignore': 'Git ignore patterns',
533
+ 'LICENSE': 'Project license information',
534
+ 'index.ts': 'Main entry point',
535
+ 'index.js': 'Main entry point',
536
+ '.env.example': 'Environment variable template'
537
+ };
538
+ if (descriptions[basename]) {
539
+ keyFiles.push({
540
+ relativePath: file.relativePath,
541
+ description: descriptions[basename]
542
+ });
543
+ }
544
+ });
545
+ return keyFiles;
546
+ }
547
+ createSimplifiedTree(repoStructure) {
548
+ const tree = {};
549
+ // Build directory structure
550
+ repoStructure.files.forEach(file => {
551
+ const parts = file.relativePath.split(path.sep);
552
+ if (parts.length > 1) {
553
+ const dir = parts[0];
554
+ if (!tree[dir])
555
+ tree[dir] = new Set();
556
+ if (parts.length === 2) {
557
+ tree[dir].add(parts[1]);
558
+ }
559
+ }
560
+ });
561
+ // Create tree visualization
562
+ let result = '';
563
+ const dirs = Object.keys(tree).sort();
564
+ dirs.forEach((dir, index) => {
565
+ const isLast = index === dirs.length - 1;
566
+ result += `${isLast ? '└── ' : '├── '}${dir}/\n`;
567
+ const files = Array.from(tree[dir]).slice(0, 3);
568
+ files.forEach((file, fIndex) => {
569
+ const isLastFile = fIndex === files.length - 1 && tree[dir].size <= 3;
570
+ result += `${isLast ? ' ' : '│ '}${isLastFile ? '└── ' : '├── '}${file}\n`;
571
+ });
572
+ if (tree[dir].size > 3) {
573
+ result += `${isLast ? ' ' : '│ '}└── ... (${tree[dir].size - 3} more files)\n`;
574
+ }
575
+ });
576
+ return result || 'No subdirectories found';
577
+ }
578
+ getConfigDescription(filePath) {
579
+ const descriptions = {
580
+ 'package.json': 'Node.js dependencies and scripts',
581
+ 'tsconfig.json': 'TypeScript compilation settings',
582
+ '.env': 'Environment variables',
583
+ '.env.example': 'Environment variable template',
584
+ 'jest.config.js': 'Jest testing configuration'
585
+ };
586
+ const basename = path.basename(filePath);
587
+ return descriptions[basename] || basename.replace(/\.[^.]+$/, '');
588
+ }
589
+ slugify(text) {
590
+ return text
591
+ .toLowerCase()
592
+ .replace(/\s+/g, '-')
593
+ .replace(/[^a-z0-9-]/g, '');
594
+ }
595
+ formatBytes(bytes) {
596
+ if (bytes === 0)
597
+ return '0 Bytes';
598
+ const k = 1024;
599
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
600
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
601
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
602
+ }
603
+ async generateDevelopmentGuide(repoStructure, docsDir, verbose) {
604
+ const fileName = 'DEVELOPMENT.md';
605
+ if (verbose) {
606
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
607
+ }
608
+ const developmentGuide = await this.createDevelopmentGuide(repoStructure);
609
+ const devPath = path.join(docsDir, fileName);
610
+ await fs.writeFile(devPath, developmentGuide);
611
+ if (verbose) {
612
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
613
+ }
614
+ }
615
+ async generateDeploymentGuide(repoStructure, docsDir, verbose) {
616
+ const fileName = 'DEPLOYMENT.md';
617
+ if (verbose) {
618
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
619
+ }
620
+ const deploymentGuide = await this.createDeploymentGuide(repoStructure);
621
+ const deployPath = path.join(docsDir, fileName);
622
+ await fs.writeFile(deployPath, deploymentGuide);
623
+ if (verbose) {
624
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
625
+ }
626
+ }
627
+ async generateTroubleshootingGuide(repoStructure, docsDir, verbose) {
628
+ const fileName = 'TROUBLESHOOTING.md';
629
+ if (verbose) {
630
+ console.log(chalk_1.default.blue(`📄 Creating ${fileName}...`));
631
+ }
632
+ const troubleshootingGuide = await this.createTroubleshootingGuide(repoStructure);
633
+ const troublePath = path.join(docsDir, fileName);
634
+ await fs.writeFile(troublePath, troubleshootingGuide);
635
+ if (verbose) {
636
+ console.log(chalk_1.default.green(`✅ Created ${fileName}`));
637
+ }
638
+ }
639
+ async createDevelopmentGuide(repoStructure) {
640
+ const moduleGroups = this.getModuleGroups(repoStructure);
641
+ const configFiles = this.getConfigurationFiles(repoStructure);
642
+ const packageInfo = this.getPackageInfo(repoStructure);
643
+ const context = `Repository: ${repoStructure.rootPath}
644
+ Total Files: ${repoStructure.totalFiles}
645
+ Modules: ${moduleGroups.map(m => m.name).join(', ')}
646
+ Configuration Files: ${configFiles.map(f => path.basename(f.relativePath)).join(', ')}
647
+ Package Info: ${JSON.stringify(packageInfo, null, 2)}
648
+
649
+ Module Structure:
650
+ ${moduleGroups.map(m => `- ${m.name}: ${m.description} (${m.files.length} files)`).join('\n')}`;
651
+ return await this.llmClient.generateText(`Create a comprehensive development guide for this project. Include:
652
+
653
+ 1. Getting Started (setup instructions)
654
+ 2. Development Environment Requirements
655
+ 3. Project Structure Overview
656
+ 4. Development Workflow
657
+ 5. Code Style and Standards
658
+ 6. Testing Guidelines
659
+ 7. Debugging Tips
660
+ 8. Build Process
661
+ 9. Contributing Guidelines
662
+
663
+ Format as clean Markdown with proper headings and code blocks.`, context);
664
+ }
665
+ async createDeploymentGuide(repoStructure) {
666
+ const packageInfo = this.getPackageInfo(repoStructure);
667
+ const configFiles = this.getConfigurationFiles(repoStructure);
668
+ const hasDockerfile = repoStructure.files.some(f => f.relativePath.toLowerCase().includes('dockerfile'));
669
+ const hasKubernetes = repoStructure.files.some(f => f.relativePath.includes('k8s') || f.relativePath.includes('kubernetes'));
670
+ const context = `Repository: ${repoStructure.rootPath}
671
+ Package Info: ${JSON.stringify(packageInfo, null, 2)}
672
+ Configuration Files: ${configFiles.map(f => path.basename(f.relativePath)).join(', ')}
673
+ Has Dockerfile: ${hasDockerfile}
674
+ Has Kubernetes: ${hasKubernetes}
675
+ Project Type: ${this.detectProjectType(repoStructure)}`;
676
+ return await this.llmClient.generateText(`Create a comprehensive deployment guide for this project. Include:
677
+
678
+ 1. Prerequisites and Dependencies
679
+ 2. Environment Configuration
680
+ 3. Build Process for Production
681
+ 4. Deployment Options (based on project type)
682
+ 5. Environment Variables and Secrets
683
+ 6. Database Setup (if applicable)
684
+ 7. Monitoring and Health Checks
685
+ 8. Rollback Procedures
686
+ 9. Security Considerations
687
+ 10. Performance Optimization
688
+
689
+ Adapt the guide based on the project type and available configuration files.
690
+ Format as clean Markdown with proper headings and code blocks.`, context);
691
+ }
692
+ async createTroubleshootingGuide(repoStructure) {
693
+ const moduleGroups = this.getModuleGroups(repoStructure);
694
+ const packageInfo = this.getPackageInfo(repoStructure);
695
+ const projectType = this.detectProjectType(repoStructure);
696
+ const context = `Repository: ${repoStructure.rootPath}
697
+ Project Type: ${projectType}
698
+ Package Info: ${JSON.stringify(packageInfo, null, 2)}
699
+ Modules: ${moduleGroups.map(m => `${m.name} (${m.files.length} files)`).join(', ')}`;
700
+ return await this.llmClient.generateText(`Create a comprehensive troubleshooting guide for this ${projectType} project. Include:
701
+
702
+ 1. Common Issues and Solutions
703
+ 2. Development Environment Problems
704
+ 3. Build and Compilation Errors
705
+ 4. Runtime Errors and Debugging
706
+ 5. Performance Issues
707
+ 6. Dependency Problems
708
+ 7. Configuration Issues
709
+ 8. Testing Problems
710
+ 9. Deployment Issues
711
+ 10. Debugging Tools and Techniques
712
+ 11. Log Analysis
713
+ 12. FAQ Section
714
+
715
+ Focus on practical solutions and include code examples where helpful.
716
+ Format as clean Markdown with proper headings and code blocks.`, context);
717
+ }
718
+ detectProjectType(repoStructure) {
719
+ const packageJson = repoStructure.files.find(f => f.relativePath === 'package.json');
720
+ if (packageJson) {
721
+ return 'Node.js/JavaScript';
722
+ }
723
+ const cargoToml = repoStructure.files.find(f => f.relativePath === 'Cargo.toml');
724
+ if (cargoToml) {
725
+ return 'Rust';
726
+ }
727
+ const goMod = repoStructure.files.find(f => f.relativePath === 'go.mod');
728
+ if (goMod) {
729
+ return 'Go';
730
+ }
731
+ const pythonFiles = repoStructure.files.filter(f => f.extension === '.py');
732
+ if (pythonFiles.length > 0) {
733
+ return 'Python';
734
+ }
735
+ const javaFiles = repoStructure.files.filter(f => f.extension === '.java');
736
+ if (javaFiles.length > 0) {
737
+ return 'Java';
738
+ }
739
+ return 'Mixed/Other';
740
+ }
741
+ getConfigurationFiles(repoStructure) {
742
+ const configPatterns = [
743
+ 'package.json',
744
+ 'tsconfig.json',
745
+ 'jest.config.js',
746
+ 'webpack.config.js',
747
+ '.env',
748
+ '.env.example',
749
+ 'docker-compose.yml',
750
+ 'Dockerfile',
751
+ 'cargo.toml',
752
+ 'go.mod',
753
+ 'requirements.txt',
754
+ 'pyproject.toml'
755
+ ];
756
+ return repoStructure.files.filter((file) => configPatterns.some(pattern => file.relativePath.toLowerCase().includes(pattern.toLowerCase())));
757
+ }
758
+ getPackageInfo(repoStructure) {
759
+ const packageJson = repoStructure.files.find(f => f.relativePath === 'package.json');
760
+ if (packageJson) {
761
+ try {
762
+ // Read package.json content - this is a simplified approach
763
+ // In practice, you might want to read the actual file content
764
+ return {
765
+ type: 'Node.js project',
766
+ configFile: 'package.json',
767
+ hasScripts: true
768
+ };
769
+ }
770
+ catch {
771
+ return { type: 'Node.js project', configFile: 'package.json' };
772
+ }
773
+ }
774
+ const cargoToml = repoStructure.files.find(f => f.relativePath === 'Cargo.toml');
775
+ if (cargoToml) {
776
+ return { type: 'Rust project', configFile: 'Cargo.toml' };
777
+ }
778
+ const goMod = repoStructure.files.find(f => f.relativePath === 'go.mod');
779
+ if (goMod) {
780
+ return { type: 'Go project', configFile: 'go.mod' };
781
+ }
782
+ return { type: 'Generic project', configFile: 'none' };
783
+ }
784
+ }
785
+ exports.DocumentationGenerator = DocumentationGenerator;
786
+ //# sourceMappingURL=documentationGenerator.js.map