ai-first-cli 1.3.5 → 1.3.8

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 (126) hide show
  1. package/CHANGELOG.md +186 -0
  2. package/README.es.md +68 -0
  3. package/README.md +53 -15
  4. package/ai/graph/knowledge-graph.json +1 -1
  5. package/ai-context/index-state.json +86 -2
  6. package/dist/analyzers/architecture.d.ts.map +1 -1
  7. package/dist/analyzers/architecture.js +72 -5
  8. package/dist/analyzers/architecture.js.map +1 -1
  9. package/dist/analyzers/entrypoints.d.ts.map +1 -1
  10. package/dist/analyzers/entrypoints.js +253 -0
  11. package/dist/analyzers/entrypoints.js.map +1 -1
  12. package/dist/analyzers/symbols.d.ts.map +1 -1
  13. package/dist/analyzers/symbols.js +47 -2
  14. package/dist/analyzers/symbols.js.map +1 -1
  15. package/dist/analyzers/techStack.d.ts.map +1 -1
  16. package/dist/analyzers/techStack.js +86 -0
  17. package/dist/analyzers/techStack.js.map +1 -1
  18. package/dist/commands/ai-first.d.ts.map +1 -1
  19. package/dist/commands/ai-first.js +78 -4
  20. package/dist/commands/ai-first.js.map +1 -1
  21. package/dist/config/configLoader.d.ts +6 -0
  22. package/dist/config/configLoader.d.ts.map +1 -0
  23. package/dist/config/configLoader.js +232 -0
  24. package/dist/config/configLoader.js.map +1 -0
  25. package/dist/config/index.d.ts +3 -0
  26. package/dist/config/index.d.ts.map +1 -0
  27. package/dist/config/index.js +2 -0
  28. package/dist/config/index.js.map +1 -0
  29. package/dist/config/types.d.ts +101 -0
  30. package/dist/config/types.d.ts.map +1 -0
  31. package/dist/config/types.js +2 -0
  32. package/dist/config/types.js.map +1 -0
  33. package/dist/core/content/contentProcessor.d.ts +4 -0
  34. package/dist/core/content/contentProcessor.d.ts.map +1 -0
  35. package/dist/core/content/contentProcessor.js +235 -0
  36. package/dist/core/content/contentProcessor.js.map +1 -0
  37. package/dist/core/content/index.d.ts +3 -0
  38. package/dist/core/content/index.d.ts.map +1 -0
  39. package/dist/core/content/index.js +2 -0
  40. package/dist/core/content/index.js.map +1 -0
  41. package/dist/core/content/types.d.ts +32 -0
  42. package/dist/core/content/types.d.ts.map +1 -0
  43. package/dist/core/content/types.js +2 -0
  44. package/dist/core/content/types.js.map +1 -0
  45. package/dist/core/gitAnalyzer.d.ts +14 -0
  46. package/dist/core/gitAnalyzer.d.ts.map +1 -1
  47. package/dist/core/gitAnalyzer.js +98 -0
  48. package/dist/core/gitAnalyzer.js.map +1 -1
  49. package/dist/core/multiRepo/index.d.ts +3 -0
  50. package/dist/core/multiRepo/index.d.ts.map +1 -0
  51. package/dist/core/multiRepo/index.js +2 -0
  52. package/dist/core/multiRepo/index.js.map +1 -0
  53. package/dist/core/multiRepo/multiRepoScanner.d.ts +18 -0
  54. package/dist/core/multiRepo/multiRepoScanner.d.ts.map +1 -0
  55. package/dist/core/multiRepo/multiRepoScanner.js +131 -0
  56. package/dist/core/multiRepo/multiRepoScanner.js.map +1 -0
  57. package/dist/core/rag/index.d.ts +3 -0
  58. package/dist/core/rag/index.d.ts.map +1 -0
  59. package/dist/core/rag/index.js +2 -0
  60. package/dist/core/rag/index.js.map +1 -0
  61. package/dist/core/rag/vectorIndex.d.ts +28 -0
  62. package/dist/core/rag/vectorIndex.d.ts.map +1 -0
  63. package/dist/core/rag/vectorIndex.js +71 -0
  64. package/dist/core/rag/vectorIndex.js.map +1 -0
  65. package/dist/mcp/index.d.ts +2 -0
  66. package/dist/mcp/index.d.ts.map +1 -0
  67. package/dist/mcp/index.js +2 -0
  68. package/dist/mcp/index.js.map +1 -0
  69. package/dist/mcp/server.d.ts +7 -0
  70. package/dist/mcp/server.d.ts.map +1 -0
  71. package/dist/mcp/server.js +154 -0
  72. package/dist/mcp/server.js.map +1 -0
  73. package/dist/utils/fileUtils.d.ts.map +1 -1
  74. package/dist/utils/fileUtils.js +5 -0
  75. package/dist/utils/fileUtils.js.map +1 -1
  76. package/docs/planning/evaluator-v1.0.0/README.md +112 -0
  77. package/docs/planning/evaluator-v1.0.0/improvements_plan_2026-03-28.md +237 -0
  78. package/package.json +13 -3
  79. package/src/analyzers/architecture.ts +75 -6
  80. package/src/analyzers/entrypoints.ts +285 -0
  81. package/src/analyzers/symbols.ts +52 -2
  82. package/src/analyzers/techStack.ts +90 -0
  83. package/src/commands/ai-first.ts +83 -4
  84. package/src/config/configLoader.ts +274 -0
  85. package/src/config/index.ts +27 -0
  86. package/src/config/types.ts +117 -0
  87. package/src/core/content/contentProcessor.ts +292 -0
  88. package/src/core/content/index.ts +9 -0
  89. package/src/core/content/types.ts +35 -0
  90. package/src/core/gitAnalyzer.ts +130 -0
  91. package/src/core/multiRepo/index.ts +2 -0
  92. package/src/core/multiRepo/multiRepoScanner.ts +177 -0
  93. package/src/core/rag/index.ts +2 -0
  94. package/src/core/rag/vectorIndex.ts +105 -0
  95. package/src/mcp/index.ts +1 -0
  96. package/src/mcp/server.ts +179 -0
  97. package/src/utils/fileUtils.ts +5 -0
  98. package/tests/entrypoints-languages.test.ts +373 -0
  99. package/tests/framework-detection.test.ts +296 -0
  100. package/tests/v1.3.8-integration.test.ts +361 -0
  101. package/BETA_EVALUATION_REPORT.md +0 -151
  102. package/ai-context/context/flows/App.json +0 -17
  103. package/ai-context/context/flows/DashboardPage.json +0 -14
  104. package/ai-context/context/flows/LoginPage.json +0 -14
  105. package/ai-context/context/flows/admin.json +0 -10
  106. package/ai-context/context/flows/androidresources.json +0 -11
  107. package/ai-context/context/flows/authController.json +0 -14
  108. package/ai-context/context/flows/entrypoints.json +0 -9
  109. package/ai-context/context/flows/fastapiAdapter.json +0 -14
  110. package/ai-context/context/flows/fastapiadapter.json +0 -11
  111. package/ai-context/context/flows/index.json +0 -19
  112. package/ai-context/context/flows/indexer.json +0 -9
  113. package/ai-context/context/flows/indexstate.json +0 -9
  114. package/ai-context/context/flows/init.json +0 -22
  115. package/ai-context/context/flows/main.json +0 -18
  116. package/ai-context/context/flows/mainactivity.json +0 -9
  117. package/ai-context/context/flows/models.json +0 -15
  118. package/ai-context/context/flows/posts.json +0 -15
  119. package/ai-context/context/flows/repoMapper.json +0 -20
  120. package/ai-context/context/flows/repomapper.json +0 -11
  121. package/ai-context/context/flows/serializers.json +0 -10
  122. package/ai-context-evaluation-report-1774223059505.md +0 -206
  123. package/dist/scripts/ai-context-evaluator.js +0 -367
  124. package/quick-evaluation-report-1774396002305.md +0 -64
  125. package/quick-evaluator.ts +0 -200
  126. package/scripts/ai-context-evaluator.ts +0 -440
@@ -31,6 +31,7 @@ import { runIncrementalUpdate, detectChangedFiles } from "../core/incrementalAna
31
31
  import { generateAllSchema } from "../core/schema.js";
32
32
  import { Database } from "sql.js";
33
33
  import ora from "ora";
34
+ import { startMCP } from "../mcp/index.js";
34
35
  import process from "process";
35
36
 
36
37
  const __filename = fileURLToPath(import.meta.url);
@@ -1077,6 +1078,8 @@ Options:
1077
1078
  } else if (command === 'init' || !command) {
1078
1079
  // Init command - generate all context files
1079
1080
  if (command === 'init') args.shift();
1081
+
1082
+ let preset: string | undefined;
1080
1083
 
1081
1084
  for (let i = 0; i < args.length; i++) {
1082
1085
  const arg = args[i];
@@ -1089,6 +1092,10 @@ Options:
1089
1092
  case "-o":
1090
1093
  options.outputDir = args[++i];
1091
1094
  break;
1095
+ case "--preset":
1096
+ case "-p":
1097
+ preset = args[++i];
1098
+ break;
1092
1099
  case "--help":
1093
1100
  case "-h":
1094
1101
  console.log(`
@@ -1106,18 +1113,45 @@ Commands:
1106
1113
  doctor Check repository health and AI readiness
1107
1114
  explore <module> Explore module dependencies
1108
1115
  map Generate repository map (files, modules, graph)
1109
- adapters List available adapters
1110
- explore <module> Explore module dependencies
1111
- map Generate repository map (files, modules, graph)
1116
+ adapters List available adapters
1117
+ git Show git activity and recent changes
1118
+ graph Build knowledge graph
1119
+ update Update context incrementally
1120
+ mcp Start MCP server for AI agents
1112
1121
 
1113
1122
  Options:
1114
1123
  -r, --root <dir> Root directory to scan (default: current directory)
1115
1124
  -o, --output <dir> Output directory (default: ./ai-context)
1125
+ -p, --preset <name> Use preset (full, quick, api, docs)
1116
1126
  -h, --help Show help message
1127
+
1128
+ Presets:
1129
+ full Complete analysis with all features
1130
+ quick Fast analysis for development iterations
1131
+ api Focus on API endpoints and services
1132
+ docs Documentation files only
1117
1133
  `);
1118
1134
  process.exit(0);
1119
1135
  }
1120
1136
  }
1137
+
1138
+ const rootDir = options.rootDir || process.cwd();
1139
+ const configPath = path.join(rootDir, 'ai-first.config.json');
1140
+ if (fs.existsSync(configPath)) {
1141
+ try {
1142
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1143
+ if (config.output?.directory && !options.outputDir) {
1144
+ options.outputDir = path.join(rootDir, config.output.directory);
1145
+ }
1146
+ if (config.preset && !preset) {
1147
+ preset = config.preset;
1148
+ }
1149
+ } catch {}
1150
+ }
1151
+
1152
+ if (preset) {
1153
+ console.log(`\n🎛️ Using preset: ${preset}\n`);
1154
+ }
1121
1155
 
1122
1156
  runAIFirst(options).then((result) => {
1123
1157
  process.exit(result.success ? 0 : 1);
@@ -1491,7 +1525,52 @@ Examples:
1491
1525
  }
1492
1526
 
1493
1527
  process.exit(0);
1494
- process.exit(0);
1528
+ } else if (command === 'mcp') {
1529
+ // MCP command - start Model Context Protocol server
1530
+ args.shift();
1531
+
1532
+ if (args.includes('--help') || args.includes('-h')) {
1533
+ console.log(`
1534
+ ai-first mcp - Start Model Context Protocol server
1535
+
1536
+ Usage: ai-first mcp [options]
1537
+
1538
+ Options:
1539
+ -r, --root <dir> Root directory to scan (default: current directory)
1540
+ -h, --help Show help message
1541
+
1542
+ Description:
1543
+ Starts an MCP server that allows AI agents (Claude Desktop, etc.) to
1544
+ query repository context using the Model Context Protocol.
1545
+
1546
+ The server provides these tools:
1547
+ - generate_context: Generate AI context for the repository
1548
+ - index_repo: Create SQLite index for fast queries
1549
+ - query_symbol: Look up symbols by name
1550
+ - get_architecture: Get architecture analysis
1551
+ - get_tech_stack: Get technology stack information
1552
+
1553
+ Examples:
1554
+ ai-first mcp # Start MCP server in current directory
1555
+ ai-first mcp --root ./my-project # Start with specific root directory
1556
+ `);
1557
+ process.exit(0);
1558
+ }
1559
+
1560
+ let rootDir = process.cwd();
1561
+
1562
+ for (let i = 0; i < args.length; i++) {
1563
+ const arg = args[i];
1564
+ if (arg === "--root" || arg === "-r") rootDir = args[++i];
1565
+ }
1566
+
1567
+ console.log("\n🚀 Starting MCP server...\n");
1568
+ console.log(` Root directory: ${rootDir}`);
1569
+ console.log(" Protocol: stdio");
1570
+ console.log("\n The server is now running and ready to accept MCP requests.");
1571
+ console.log(" Use Ctrl+C to stop.\n");
1572
+
1573
+ startMCP({ rootDir });
1495
1574
  } else {
1496
1575
  console.log(`Unknown command: ${command}`);
1497
1576
  console.log(`Use 'ai-first --help' for usage information`);
@@ -0,0 +1,274 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import type {
4
+ AIFirstConfig,
5
+ AnalysisPreset,
6
+ ConfigLoadOptions,
7
+ ConfigLoadResult,
8
+ PresetConfig,
9
+ ValidationResult,
10
+ ValidationError,
11
+ ValidationWarning,
12
+ OutputConfig,
13
+ IndexConfig,
14
+ } from './types.js';
15
+
16
+ const DEFAULT_CONFIG_PATH = 'ai-first.config.json';
17
+
18
+ const PRESETS: Record<AnalysisPreset, PresetConfig> = {
19
+ full: {
20
+ name: 'full',
21
+ description: 'Full analysis with all analyzers enabled',
22
+ analysis: {
23
+ detailLevel: 'full',
24
+ inclusionLevel: 'full',
25
+ analyzers: {
26
+ architecture: { enabled: true },
27
+ techStack: { enabled: true },
28
+ entrypoints: { enabled: true },
29
+ conventions: { enabled: true },
30
+ symbols: { enabled: true },
31
+ dependencies: { enabled: true },
32
+ aiRules: { enabled: true },
33
+ },
34
+ },
35
+ output: {
36
+ directory: 'ai-context',
37
+ formats: ['md', 'json'],
38
+ prettyPrint: true,
39
+ includeMetadata: true,
40
+ },
41
+ index: {
42
+ enabled: true,
43
+ type: 'sqlite',
44
+ incremental: true,
45
+ },
46
+ },
47
+ quick: {
48
+ name: 'quick',
49
+ description: 'Fast analysis with basic information',
50
+ analysis: {
51
+ detailLevel: 'skeleton',
52
+ inclusionLevel: 'directory',
53
+ maxFileSize: 10000,
54
+ analyzers: {
55
+ architecture: { enabled: true },
56
+ techStack: { enabled: true },
57
+ entrypoints: { enabled: true },
58
+ conventions: { enabled: false },
59
+ symbols: { enabled: false },
60
+ dependencies: { enabled: false },
61
+ aiRules: { enabled: false },
62
+ },
63
+ },
64
+ output: {
65
+ directory: 'ai-context',
66
+ formats: ['md'],
67
+ prettyPrint: false,
68
+ includeMetadata: false,
69
+ },
70
+ index: {
71
+ enabled: false,
72
+ type: 'memory',
73
+ },
74
+ },
75
+ api: {
76
+ name: 'api',
77
+ description: 'Focused on API and backend analysis',
78
+ analysis: {
79
+ detailLevel: 'signatures',
80
+ inclusionLevel: 'compress',
81
+ analyzers: {
82
+ architecture: { enabled: true },
83
+ techStack: { enabled: true },
84
+ entrypoints: { enabled: true },
85
+ conventions: { enabled: true },
86
+ symbols: { enabled: true },
87
+ dependencies: { enabled: true },
88
+ aiRules: { enabled: false },
89
+ },
90
+ },
91
+ output: {
92
+ directory: 'ai-context',
93
+ formats: ['md', 'json'],
94
+ prettyPrint: true,
95
+ includeMetadata: true,
96
+ },
97
+ index: {
98
+ enabled: true,
99
+ type: 'sqlite',
100
+ incremental: true,
101
+ },
102
+ },
103
+ docs: {
104
+ name: 'docs',
105
+ description: 'Generate documentation-focused output',
106
+ analysis: {
107
+ detailLevel: 'full',
108
+ inclusionLevel: 'full',
109
+ analyzers: {
110
+ architecture: { enabled: true },
111
+ techStack: { enabled: true },
112
+ entrypoints: { enabled: true },
113
+ conventions: { enabled: true },
114
+ symbols: { enabled: true },
115
+ dependencies: { enabled: false },
116
+ aiRules: { enabled: false },
117
+ },
118
+ },
119
+ output: {
120
+ directory: 'ai-context',
121
+ formats: ['md', 'html'],
122
+ prettyPrint: true,
123
+ includeMetadata: true,
124
+ },
125
+ index: {
126
+ enabled: false,
127
+ type: 'memory',
128
+ },
129
+ },
130
+ };
131
+
132
+ const DEFAULT_CONFIG: AIFirstConfig = {
133
+ version: '1.0.0',
134
+ preset: 'full',
135
+ analysis: PRESETS.full.analysis as NonNullable<AIFirstConfig['analysis']>,
136
+ output: PRESETS.full.output as OutputConfig,
137
+ index: PRESETS.full.index as IndexConfig,
138
+ };
139
+
140
+ function validateConfig(config: unknown): ValidationResult {
141
+ const errors: ValidationError[] = [];
142
+ const warnings: ValidationWarning[] = [];
143
+
144
+ if (!config || typeof config !== 'object') {
145
+ errors.push({ field: 'root', message: 'Config must be an object' });
146
+ return { valid: false, errors, warnings };
147
+ }
148
+
149
+ const cfg = config as Record<string, unknown>;
150
+
151
+ if (!cfg.version || typeof cfg.version !== 'string') {
152
+ errors.push({ field: 'version', message: 'Version is required and must be a string' });
153
+ }
154
+
155
+ if (cfg.preset !== undefined) {
156
+ const validPresets: AnalysisPreset[] = ['full', 'quick', 'api', 'docs'];
157
+ if (!validPresets.includes(cfg.preset as AnalysisPreset)) {
158
+ errors.push({
159
+ field: 'preset',
160
+ message: `Invalid preset. Must be one of: ${validPresets.join(', ')}`,
161
+ value: cfg.preset,
162
+ });
163
+ }
164
+ }
165
+
166
+ if (cfg.analysis && typeof cfg.analysis !== 'object') {
167
+ errors.push({ field: 'analysis', message: 'Analysis must be an object' });
168
+ }
169
+
170
+ if (cfg.output && typeof cfg.output !== 'object') {
171
+ errors.push({ field: 'output', message: 'Output must be an object' });
172
+ }
173
+
174
+ if (cfg.index && typeof cfg.index !== 'object') {
175
+ errors.push({ field: 'index', message: 'Index must be an object' });
176
+ }
177
+
178
+ return { valid: errors.length === 0, errors, warnings };
179
+ }
180
+
181
+ function mergeConfig(base: AIFirstConfig, override: Partial<AIFirstConfig>): AIFirstConfig {
182
+ const result: AIFirstConfig = {
183
+ ...base,
184
+ ...override,
185
+ };
186
+
187
+ if (override.analysis) {
188
+ result.analysis = { ...base.analysis, ...override.analysis };
189
+ }
190
+ if (override.output) {
191
+ result.output = { ...base.output, ...override.output } as OutputConfig;
192
+ }
193
+ if (override.index) {
194
+ result.index = { ...base.index, ...override.index } as IndexConfig;
195
+ }
196
+
197
+ return result;
198
+ }
199
+
200
+ export function getPreset(name: AnalysisPreset): PresetConfig | undefined {
201
+ return PRESETS[name];
202
+ }
203
+
204
+ export function listPresets(): PresetConfig[] {
205
+ return Object.values(PRESETS);
206
+ }
207
+
208
+ export function loadConfig(options: ConfigLoadOptions = {}): ConfigLoadResult {
209
+ const {
210
+ configPath = DEFAULT_CONFIG_PATH,
211
+ preset,
212
+ overrides,
213
+ validate = true,
214
+ throwOnError = false,
215
+ } = options;
216
+
217
+ let config: AIFirstConfig = { ...DEFAULT_CONFIG };
218
+ let source: ConfigLoadResult['source'] = 'default';
219
+
220
+ if (fs.existsSync(configPath)) {
221
+ try {
222
+ const fileContent = fs.readFileSync(configPath, 'utf-8');
223
+ const loadedConfig = JSON.parse(fileContent) as Partial<AIFirstConfig>;
224
+ config = mergeConfig(DEFAULT_CONFIG, loadedConfig);
225
+ source = 'file';
226
+ } catch (error) {
227
+ const parseError: ValidationError = {
228
+ field: 'configFile',
229
+ message: `Failed to parse config file: ${error instanceof Error ? error.message : String(error)}`,
230
+ value: configPath,
231
+ };
232
+ if (throwOnError) {
233
+ throw new Error(parseError.message);
234
+ }
235
+ return {
236
+ config: DEFAULT_CONFIG,
237
+ source: 'default',
238
+ validation: { valid: false, errors: [parseError], warnings: [] },
239
+ };
240
+ }
241
+ }
242
+
243
+ if (preset && PRESETS[preset]) {
244
+ const p = PRESETS[preset];
245
+ const presetData: Partial<AIFirstConfig> = {
246
+ analysis: p.analysis as AIFirstConfig['analysis'],
247
+ output: p.output as AIFirstConfig['output'],
248
+ index: p.index as AIFirstConfig['index'],
249
+ };
250
+ config = mergeConfig(config, presetData);
251
+ source = source === 'default' ? 'preset' : 'merged';
252
+ }
253
+
254
+ if (overrides) {
255
+ config = mergeConfig(config, overrides);
256
+ source = 'merged';
257
+ }
258
+
259
+ const validation = validateConfig(config);
260
+
261
+ if (!validation.valid && throwOnError) {
262
+ const errorMessages = validation.errors.map(e => e.message).join('; ');
263
+ throw new Error(`Configuration validation failed: ${errorMessages}`);
264
+ }
265
+
266
+ return { config, source, validation };
267
+ }
268
+
269
+ export function resolveConfigPath(customPath?: string): string {
270
+ if (customPath) {
271
+ return path.resolve(customPath);
272
+ }
273
+ return path.resolve(DEFAULT_CONFIG_PATH);
274
+ }
@@ -0,0 +1,27 @@
1
+ export type {
2
+ AnalysisPreset,
3
+ ConfigDetailLevel,
4
+ ConfigInclusionLevel,
5
+ FilePatternConfig,
6
+ AnalyzerConfig,
7
+ AnalysisConfig,
8
+ FileInclusionConfig,
9
+ OutputConfig,
10
+ GitConfig,
11
+ IndexConfig,
12
+ ContextConfig,
13
+ PresetConfig,
14
+ AIFirstConfig,
15
+ ValidationResult,
16
+ ValidationError,
17
+ ValidationWarning,
18
+ ConfigLoadOptions,
19
+ ConfigLoadResult,
20
+ } from './types.js';
21
+
22
+ export {
23
+ loadConfig,
24
+ getPreset,
25
+ listPresets,
26
+ resolveConfigPath,
27
+ } from './configLoader.js';
@@ -0,0 +1,117 @@
1
+ export type AnalysisPreset = 'full' | 'quick' | 'api' | 'docs';
2
+
3
+ export type ConfigDetailLevel = 'full' | 'signatures' | 'skeleton';
4
+
5
+ export type ConfigInclusionLevel = 'full' | 'compress' | 'directory' | 'exclude';
6
+
7
+ export interface FilePatternConfig {
8
+ include?: string[];
9
+ exclude?: string[];
10
+ }
11
+
12
+ export interface AnalyzerConfig {
13
+ enabled: boolean;
14
+ options?: Record<string, unknown>;
15
+ }
16
+
17
+ export interface AnalysisConfig {
18
+ preset?: AnalysisPreset;
19
+ detailLevel?: ConfigDetailLevel;
20
+ inclusionLevel?: ConfigInclusionLevel;
21
+ filePatterns?: FilePatternConfig;
22
+ maxFileSize?: number;
23
+ includePatterns?: string[];
24
+ excludePatterns?: string[];
25
+ analyzers?: {
26
+ architecture?: AnalyzerConfig;
27
+ techStack?: AnalyzerConfig;
28
+ entrypoints?: AnalyzerConfig;
29
+ conventions?: AnalyzerConfig;
30
+ symbols?: AnalyzerConfig;
31
+ dependencies?: AnalyzerConfig;
32
+ aiRules?: AnalyzerConfig;
33
+ };
34
+ }
35
+
36
+ export interface FileInclusionConfig {
37
+ level: ConfigInclusionLevel;
38
+ patterns: string[];
39
+ maxFileSize?: number;
40
+ }
41
+
42
+ export interface OutputConfig {
43
+ directory: string;
44
+ formats: ('md' | 'json' | 'html')[];
45
+ prettyPrint?: boolean;
46
+ includeMetadata?: boolean;
47
+ }
48
+
49
+ export interface GitConfig {
50
+ includeCommits?: number;
51
+ excludePatterns?: string[];
52
+ }
53
+
54
+ export interface IndexConfig {
55
+ enabled: boolean;
56
+ type: 'sqlite' | 'memory';
57
+ incremental?: boolean;
58
+ watch?: boolean;
59
+ }
60
+
61
+ export interface ContextConfig {
62
+ maxTokens?: number;
63
+ includeEmbeddings?: boolean;
64
+ semanticSearch?: boolean;
65
+ maxResults?: number;
66
+ }
67
+
68
+ export interface PresetConfig {
69
+ name: AnalysisPreset;
70
+ description: string;
71
+ analysis: Partial<AnalysisConfig>;
72
+ output: Partial<OutputConfig>;
73
+ index: Partial<IndexConfig>;
74
+ }
75
+
76
+ export interface AIFirstConfig {
77
+ version: string;
78
+ preset?: AnalysisPreset;
79
+ analysis?: AnalysisConfig;
80
+ output?: OutputConfig;
81
+ index?: IndexConfig;
82
+ context?: ContextConfig;
83
+ git?: GitConfig;
84
+ fileInclusion?: FileInclusionConfig;
85
+ }
86
+
87
+ export interface ValidationResult {
88
+ valid: boolean;
89
+ errors: ValidationError[];
90
+ warnings: ValidationWarning[];
91
+ }
92
+
93
+ export interface ValidationError {
94
+ field: string;
95
+ message: string;
96
+ value?: unknown;
97
+ }
98
+
99
+ export interface ValidationWarning {
100
+ field: string;
101
+ message: string;
102
+ suggestion?: string;
103
+ }
104
+
105
+ export interface ConfigLoadOptions {
106
+ configPath?: string;
107
+ preset?: AnalysisPreset;
108
+ overrides?: Partial<AIFirstConfig>;
109
+ validate?: boolean;
110
+ throwOnError?: boolean;
111
+ }
112
+
113
+ export interface ConfigLoadResult {
114
+ config: AIFirstConfig;
115
+ source: 'default' | 'file' | 'preset' | 'merged';
116
+ validation: ValidationResult;
117
+ }