ai-first-cli 1.3.6 → 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.
- package/CHANGELOG.md +123 -0
- package/README.es.md +14 -1
- package/README.md +14 -1
- package/ai/graph/knowledge-graph.json +1 -1
- package/ai-context/index-state.json +86 -2
- package/dist/analyzers/techStack.d.ts.map +1 -1
- package/dist/analyzers/techStack.js +43 -0
- package/dist/analyzers/techStack.js.map +1 -1
- package/dist/commands/ai-first.d.ts.map +1 -1
- package/dist/commands/ai-first.js +78 -4
- package/dist/commands/ai-first.js.map +1 -1
- package/dist/config/configLoader.d.ts +6 -0
- package/dist/config/configLoader.d.ts.map +1 -0
- package/dist/config/configLoader.js +232 -0
- package/dist/config/configLoader.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +101 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/content/contentProcessor.d.ts +4 -0
- package/dist/core/content/contentProcessor.d.ts.map +1 -0
- package/dist/core/content/contentProcessor.js +235 -0
- package/dist/core/content/contentProcessor.js.map +1 -0
- package/dist/core/content/index.d.ts +3 -0
- package/dist/core/content/index.d.ts.map +1 -0
- package/dist/core/content/index.js +2 -0
- package/dist/core/content/index.js.map +1 -0
- package/dist/core/content/types.d.ts +32 -0
- package/dist/core/content/types.d.ts.map +1 -0
- package/dist/core/content/types.js +2 -0
- package/dist/core/content/types.js.map +1 -0
- package/dist/core/gitAnalyzer.d.ts +14 -0
- package/dist/core/gitAnalyzer.d.ts.map +1 -1
- package/dist/core/gitAnalyzer.js +98 -0
- package/dist/core/gitAnalyzer.js.map +1 -1
- package/dist/core/multiRepo/index.d.ts +3 -0
- package/dist/core/multiRepo/index.d.ts.map +1 -0
- package/dist/core/multiRepo/index.js +2 -0
- package/dist/core/multiRepo/index.js.map +1 -0
- package/dist/core/multiRepo/multiRepoScanner.d.ts +18 -0
- package/dist/core/multiRepo/multiRepoScanner.d.ts.map +1 -0
- package/dist/core/multiRepo/multiRepoScanner.js +131 -0
- package/dist/core/multiRepo/multiRepoScanner.js.map +1 -0
- package/dist/core/rag/index.d.ts +3 -0
- package/dist/core/rag/index.d.ts.map +1 -0
- package/dist/core/rag/index.js +2 -0
- package/dist/core/rag/index.js.map +1 -0
- package/dist/core/rag/vectorIndex.d.ts +28 -0
- package/dist/core/rag/vectorIndex.d.ts.map +1 -0
- package/dist/core/rag/vectorIndex.js +71 -0
- package/dist/core/rag/vectorIndex.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +154 -0
- package/dist/mcp/server.js.map +1 -0
- package/docs/planning/evaluator-v1.0.0/README.md +112 -0
- package/docs/planning/evaluator-v1.0.0/improvements_plan_2026-03-28.md +237 -0
- package/package.json +13 -3
- package/src/analyzers/techStack.ts +47 -1
- package/src/commands/ai-first.ts +83 -4
- package/src/config/configLoader.ts +274 -0
- package/src/config/index.ts +27 -0
- package/src/config/types.ts +117 -0
- package/src/core/content/contentProcessor.ts +292 -0
- package/src/core/content/index.ts +9 -0
- package/src/core/content/types.ts +35 -0
- package/src/core/gitAnalyzer.ts +130 -0
- package/src/core/multiRepo/index.ts +2 -0
- package/src/core/multiRepo/multiRepoScanner.ts +177 -0
- package/src/core/rag/index.ts +2 -0
- package/src/core/rag/vectorIndex.ts +105 -0
- package/src/mcp/index.ts +1 -0
- package/src/mcp/server.ts +179 -0
- package/tests/v1.3.8-integration.test.ts +361 -0
- package/ai-context-evaluation-report-1774223059505.md +0 -206
- package/scripts/ai-context-evaluator.ts +0 -440
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { loadConfig, getPreset, listPresets } from '../src/config/configLoader.js';
|
|
6
|
+
import { processContent, classifyFile } from '../src/core/content/contentProcessor.js';
|
|
7
|
+
import { getGitBlame, formatGitBlame } from '../src/core/gitAnalyzer.js';
|
|
8
|
+
import { createVectorIndex, semanticSearch } from '../src/core/rag/vectorIndex.js';
|
|
9
|
+
import { scanMultiRepo, generateMultiRepoReport } from '../src/core/multiRepo/multiRepoScanner.js';
|
|
10
|
+
import { detectTechStack } from '../src/analyzers/techStack.js';
|
|
11
|
+
import type { FileInfo } from '../src/core/repoScanner.js';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
16
|
+
describe('v1.3.8 Features Integration Tests', () => {
|
|
17
|
+
const testDir = path.join(__dirname, 'test-temp-v138');
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
if (!fs.existsSync(testDir)) {
|
|
21
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
if (fs.existsSync(testDir)) {
|
|
27
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('Config System', () => {
|
|
32
|
+
it('should load default config when file does not exist', () => {
|
|
33
|
+
const result = loadConfig({ configPath: path.join(testDir, 'non-existent.json') });
|
|
34
|
+
expect(result.config).toBeDefined();
|
|
35
|
+
expect(result.source).toBe('default');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should load config from file', () => {
|
|
39
|
+
const configPath = path.join(testDir, 'ai-first.config.json');
|
|
40
|
+
fs.writeFileSync(configPath, JSON.stringify({
|
|
41
|
+
version: '1.0',
|
|
42
|
+
output: { directory: 'custom-ai' }
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
const result = loadConfig({ configPath });
|
|
46
|
+
expect(result.source).toBe('file');
|
|
47
|
+
expect(result.config.output?.directory).toBe('custom-ai');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should apply preset configuration', () => {
|
|
51
|
+
const result = loadConfig({
|
|
52
|
+
configPath: path.join(testDir, 'non-existent.json'),
|
|
53
|
+
preset: 'quick'
|
|
54
|
+
});
|
|
55
|
+
expect(result.source).toBe('preset');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should override config with overrides', () => {
|
|
59
|
+
const configPath = path.join(testDir, 'ai-first.config.json');
|
|
60
|
+
fs.writeFileSync(configPath, JSON.stringify({
|
|
61
|
+
version: '1.0',
|
|
62
|
+
output: { directory: 'from-file', formats: ['md'], prettyPrint: false }
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
const result = loadConfig({
|
|
66
|
+
configPath,
|
|
67
|
+
overrides: {
|
|
68
|
+
output: { directory: 'override', formats: ['md'], prettyPrint: true }
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(result.config.output?.directory).toBe('override');
|
|
73
|
+
expect(result.config.output?.prettyPrint).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should list all 4 builtin presets', () => {
|
|
77
|
+
const presets = listPresets();
|
|
78
|
+
expect(presets.length).toBeGreaterThanOrEqual(4);
|
|
79
|
+
expect(presets.some(p => p.name === 'full')).toBe(true);
|
|
80
|
+
expect(presets.some(p => p.name === 'quick')).toBe(true);
|
|
81
|
+
expect(presets.some(p => p.name === 'api')).toBe(true);
|
|
82
|
+
expect(presets.some(p => p.name === 'docs')).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should get preset by name', () => {
|
|
86
|
+
const preset = getPreset('quick');
|
|
87
|
+
expect(preset).toBeDefined();
|
|
88
|
+
expect(preset?.name).toBe('quick');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('Content Processing', () => {
|
|
93
|
+
it('should compress code with signatures mode', () => {
|
|
94
|
+
const code = `
|
|
95
|
+
/**
|
|
96
|
+
* Test function
|
|
97
|
+
*/
|
|
98
|
+
export function test(x: number): number {
|
|
99
|
+
const result = x * 2;
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
`;
|
|
103
|
+
const result = processContent(code, { detailLevel: 'signatures' });
|
|
104
|
+
expect(result.compressionRatio).toBeGreaterThan(0);
|
|
105
|
+
expect(result.tokens).toBeLessThan(code.length / 4);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should not compress with full mode', () => {
|
|
109
|
+
const code = 'function test() { return 42; }';
|
|
110
|
+
const result = processContent(code, { detailLevel: 'full' });
|
|
111
|
+
expect(result.compressionRatio).toBe(0);
|
|
112
|
+
expect(result.processedLength).toBe(code.length);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should extract signatures from TypeScript', () => {
|
|
116
|
+
const code = `
|
|
117
|
+
export function calculateTotal(items: CartItem[]): number {
|
|
118
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface CartItem {
|
|
122
|
+
price: number;
|
|
123
|
+
quantity: number;
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
const result = processContent(code, { detailLevel: 'signatures' });
|
|
127
|
+
expect(result.content).toContain('calculateTotal');
|
|
128
|
+
expect(result.content).toContain('interface CartItem');
|
|
129
|
+
expect(result.compressionRatio).toBeGreaterThan(40);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should classify files correctly', () => {
|
|
133
|
+
expect(classifyFile('test.spec.js', ['src/**/*'], [], [], ['**/*.spec.js'])).toBe('exclude');
|
|
134
|
+
expect(classifyFile('node_modules/lodash/index.js', ['src/**/*'], ['node_modules/**/*'], [], [])).toBe('compress');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('Git Blame', () => {
|
|
139
|
+
it('should return blame info for a file', () => {
|
|
140
|
+
const result = getGitBlame('.', 'package.json');
|
|
141
|
+
expect(result.filePath).toBe('package.json');
|
|
142
|
+
expect(result.lines).toBeDefined();
|
|
143
|
+
expect(result.lines.length).toBeGreaterThan(0);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should return authors map', () => {
|
|
147
|
+
const result = getGitBlame('.', 'package.json');
|
|
148
|
+
expect(result.authors).toBeInstanceOf(Map);
|
|
149
|
+
expect(result.authors.size).toBeGreaterThan(0);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should format blame as inline', () => {
|
|
153
|
+
const blame = getGitBlame('.', 'package.json');
|
|
154
|
+
const formatted = formatGitBlame(blame, 'inline');
|
|
155
|
+
expect(formatted).toContain('[');
|
|
156
|
+
expect(formatted).toContain(']');
|
|
157
|
+
expect(formatted.split('\n').length).toBeGreaterThan(1);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should format blame as block', () => {
|
|
161
|
+
const blame = getGitBlame('.', 'package.json');
|
|
162
|
+
const formatted = formatGitBlame(blame, 'block');
|
|
163
|
+
expect(formatted).toContain('//');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('RAG Vector Search', () => {
|
|
168
|
+
it('should create vector index', () => {
|
|
169
|
+
const indexPath = path.join(testDir, 'vector-index.json');
|
|
170
|
+
const index = createVectorIndex(indexPath);
|
|
171
|
+
expect(index).toBeDefined();
|
|
172
|
+
expect(typeof index.addDocument).toBe('function');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should add and search documents', () => {
|
|
176
|
+
const indexPath = path.join(testDir, 'vector-index.json');
|
|
177
|
+
const index = createVectorIndex(indexPath);
|
|
178
|
+
|
|
179
|
+
index.addDocument({
|
|
180
|
+
id: '1',
|
|
181
|
+
content: 'function authenticateUser() { }',
|
|
182
|
+
embedding: Array(100).fill(0).map((_, i) => Math.sin(i * 0.1)),
|
|
183
|
+
metadata: { filePath: 'auth.js', type: 'function' }
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
index.addDocument({
|
|
187
|
+
id: '2',
|
|
188
|
+
content: 'function processPayment() { }',
|
|
189
|
+
embedding: Array(100).fill(0).map((_, i) => Math.cos(i * 0.1)),
|
|
190
|
+
metadata: { filePath: 'payment.js', type: 'function' }
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const results = semanticSearch(index, 'user authentication', 2);
|
|
194
|
+
expect(results).toHaveLength(2);
|
|
195
|
+
expect(results[0].score).toBeGreaterThan(0);
|
|
196
|
+
expect(results[0].document).toBeDefined();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should save and load index', () => {
|
|
200
|
+
const indexPath = path.join(testDir, 'vector-index.json');
|
|
201
|
+
const index = createVectorIndex(indexPath);
|
|
202
|
+
|
|
203
|
+
index.addDocument({
|
|
204
|
+
id: '1',
|
|
205
|
+
content: 'test',
|
|
206
|
+
embedding: Array(100).fill(0.5),
|
|
207
|
+
metadata: { filePath: 'test.js' }
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
index.save();
|
|
211
|
+
expect(fs.existsSync(indexPath)).toBe(true);
|
|
212
|
+
|
|
213
|
+
const index2 = createVectorIndex(indexPath);
|
|
214
|
+
const results = semanticSearch(index2, 'test', 1);
|
|
215
|
+
expect(results).toHaveLength(1);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('Multi-Repository', () => {
|
|
220
|
+
it('should scan current repository', () => {
|
|
221
|
+
const context = scanMultiRepo({ repositories: ['.'] });
|
|
222
|
+
expect(context.repositories).toHaveLength(1);
|
|
223
|
+
expect(context.totalFiles).toBeGreaterThan(0);
|
|
224
|
+
expect(context.repositories[0].files.length).toBeGreaterThan(0);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('should generate markdown report', () => {
|
|
228
|
+
const context = scanMultiRepo({ repositories: ['.'] });
|
|
229
|
+
const report = generateMultiRepoReport(context);
|
|
230
|
+
expect(report).toContain('# Multi-Repository Context');
|
|
231
|
+
expect(report).toContain('## Summary');
|
|
232
|
+
expect(report).toContain('## Repositories');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should detect multiple repositories', () => {
|
|
236
|
+
const repo1 = path.join(testDir, 'repo1');
|
|
237
|
+
const repo2 = path.join(testDir, 'repo2');
|
|
238
|
+
fs.mkdirSync(repo1, { recursive: true });
|
|
239
|
+
fs.mkdirSync(repo2, { recursive: true });
|
|
240
|
+
fs.writeFileSync(path.join(repo1, 'file1.js'), '');
|
|
241
|
+
fs.writeFileSync(path.join(repo2, 'file2.js'), '');
|
|
242
|
+
|
|
243
|
+
const context = scanMultiRepo({ repositories: [repo1, repo2] });
|
|
244
|
+
expect(context.repositories).toHaveLength(2);
|
|
245
|
+
expect(context.totalFiles).toBe(2);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe('Django Detection (v1.3.8)', () => {
|
|
250
|
+
const DJANGO_PROJECT = path.join(__dirname, '..', 'test-projects', 'django-app');
|
|
251
|
+
|
|
252
|
+
it('should detect Django framework from Python project', () => {
|
|
253
|
+
const files: FileInfo[] = [
|
|
254
|
+
{ path: 'blog/models.py', relativePath: 'blog/models.py', name: 'models.py', extension: 'py' },
|
|
255
|
+
{ path: 'blog/views.py', relativePath: 'blog/views.py', name: 'views.py', extension: 'py' },
|
|
256
|
+
{ path: 'users/models.py', relativePath: 'users/models.py', name: 'models.py', extension: 'py' }
|
|
257
|
+
];
|
|
258
|
+
const techStack = detectTechStack(files, DJANGO_PROJECT);
|
|
259
|
+
expect(techStack.frameworks).toContain('Django');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should detect Django from requirements.txt', () => {
|
|
263
|
+
const techStackPath = path.join(DJANGO_PROJECT, 'ai-context', 'tech_stack.md');
|
|
264
|
+
expect(fs.existsSync(techStackPath)).toBe(true);
|
|
265
|
+
|
|
266
|
+
const content = fs.readFileSync(techStackPath, 'utf-8').toLowerCase();
|
|
267
|
+
expect(content).toContain('django');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should include Django in tech_stack.md frameworks section', () => {
|
|
271
|
+
const techStackPath = path.join(DJANGO_PROJECT, 'ai-context', 'tech_stack.md');
|
|
272
|
+
const content = fs.readFileSync(techStackPath, 'utf-8');
|
|
273
|
+
expect(content).toMatch(/## Frameworks\n[\s\S]*- Django/);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('should generate ai_context.md with Django context', () => {
|
|
277
|
+
const aiContextPath = path.join(DJANGO_PROJECT, 'ai-context', 'ai_context.md');
|
|
278
|
+
expect(fs.existsSync(aiContextPath)).toBe(true);
|
|
279
|
+
|
|
280
|
+
const content = fs.readFileSync(aiContextPath, 'utf-8').toLowerCase();
|
|
281
|
+
expect(content).toContain('django');
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// MCP Integration tests removed - MCP command does not exist yet
|
|
286
|
+
// TODO(julian): Add MCP tests when the feature is implemented
|
|
287
|
+
|
|
288
|
+
describe('Config Presets (v1.3.8)', () => {
|
|
289
|
+
it('should have preset available: full', () => {
|
|
290
|
+
const preset = getPreset('full');
|
|
291
|
+
expect(preset).toBeDefined();
|
|
292
|
+
expect(preset?.name).toBe('full');
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should have preset available: quick', () => {
|
|
296
|
+
const preset = getPreset('quick');
|
|
297
|
+
expect(preset).toBeDefined();
|
|
298
|
+
expect(preset?.name).toBe('quick');
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should have preset available: api', () => {
|
|
302
|
+
const preset = getPreset('api');
|
|
303
|
+
expect(preset).toBeDefined();
|
|
304
|
+
expect(preset?.name).toBe('api');
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('should have preset available: docs', () => {
|
|
308
|
+
const preset = getPreset('docs');
|
|
309
|
+
expect(preset).toBeDefined();
|
|
310
|
+
expect(preset?.name).toBe('docs');
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should list at least 4 presets', () => {
|
|
314
|
+
const presets = listPresets();
|
|
315
|
+
expect(presets.length).toBeGreaterThanOrEqual(4);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('should apply preset to config', () => {
|
|
319
|
+
const result = loadConfig({
|
|
320
|
+
configPath: path.join(testDir, 'non-existent.json'),
|
|
321
|
+
preset: 'full'
|
|
322
|
+
});
|
|
323
|
+
expect(result.source).toBe('preset');
|
|
324
|
+
expect(result.config).toBeDefined();
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
describe('Git Blame Integration (v1.3.8)', () => {
|
|
329
|
+
it('should return blame info for a file', () => {
|
|
330
|
+
const result = getGitBlame('.', 'package.json');
|
|
331
|
+
expect(result.filePath).toBe('package.json');
|
|
332
|
+
expect(result.lines).toBeDefined();
|
|
333
|
+
expect(result.lines.length).toBeGreaterThan(0);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('should return authors with contributions', () => {
|
|
337
|
+
const result = getGitBlame('.', 'package.json');
|
|
338
|
+
expect(result.authors).toBeInstanceOf(Map);
|
|
339
|
+
expect(result.authors.size).toBeGreaterThan(0);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('should format blame as inline', () => {
|
|
343
|
+
const blame = getGitBlame('.', 'package.json');
|
|
344
|
+
const formatted = formatGitBlame(blame, 'inline');
|
|
345
|
+
expect(formatted).toContain('[');
|
|
346
|
+
expect(formatted).toContain(']');
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it('should format blame as block', () => {
|
|
350
|
+
const blame = getGitBlame('.', 'package.json');
|
|
351
|
+
const formatted = formatGitBlame(blame, 'block');
|
|
352
|
+
expect(formatted).toContain('//');
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('should include blame info in summary', () => {
|
|
356
|
+
const blame = getGitBlame('.', 'package.json');
|
|
357
|
+
const formatted = formatGitBlame(blame, 'inline');
|
|
358
|
+
expect(formatted).toContain('\n');
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
# AI-Context Evaluation Report
|
|
2
|
-
|
|
3
|
-
Generated: 2026-03-22T23:44:19.504Z
|
|
4
|
-
|
|
5
|
-
## Summary
|
|
6
|
-
|
|
7
|
-
| Project | Type | Index DB | Avg Score | Key Issue |
|
|
8
|
-
|---------|------|----------|-----------|-----------|
|
|
9
|
-
| salesforce-cli | priority | ✅ | 2.0 | Fix tech_stack.md to recognize Apex/Sale... |
|
|
10
|
-
| ai-first-cli | supported | ❌ | 2.9 | Refactor architecture.md to group src/ i... |
|
|
11
|
-
| express-api | supported | ✅ | 2.9 | Fix critical inaccuracies: remove 'Conta... |
|
|
12
|
-
| nestjs-backend | supported | ✅ | 2.8 | Correct framework detection to NestJS wi... |
|
|
13
|
-
| python-cli | supported | ✅ | 2.3 | Fix critical architecture classification... |
|
|
14
|
-
| spring-boot-app | supported | ✅ | 2.6 | Fix Spring Boot framework detection and ... |
|
|
15
|
-
| android-kotlin-app | unsupported | ❌ | 2.3 | Detect and index standard Android projec... |
|
|
16
|
-
| ios-swift-app | unsupported | ❌ | 2.7 | Validate dependencies against actual rep... |
|
|
17
|
-
| go-microservice | unsupported | ❌ | 2.0 | Extract and document actual code content... |
|
|
18
|
-
| rust-cli | unsupported | ❌ | 2.1 | Parse and include main.rs content (funct... |
|
|
19
|
-
| php-vanilla | unsupported | ❌ | 2.5 | Include actual source code content or de... |
|
|
20
|
-
|
|
21
|
-
## Detailed Findings
|
|
22
|
-
|
|
23
|
-
### salesforce-cli
|
|
24
|
-
|
|
25
|
-
- **Type:** priority
|
|
26
|
-
- **Index DB:** Yes
|
|
27
|
-
- **Model Scores:**
|
|
28
|
-
- Kimi K2.5: 1.75/5
|
|
29
|
-
- GLM 5: 2.25/5
|
|
30
|
-
- MiniMax 2.7: 2/5
|
|
31
|
-
- **Top Improvements:**
|
|
32
|
-
- Fix tech_stack.md to recognize Apex/Salesforce platform and add Salesforce-specific patterns (Trigger framework, SOQL, Governor Limits)
|
|
33
|
-
- Populate entrypoints.md with actual class methods, trigger events, and API endpoints
|
|
34
|
-
- Add business logic context describing what AccountController and OpportunityController do functionally (CRUD operations, integrations, validation logic)
|
|
35
|
-
- Detect and list Apex as the primary language in tech_stack.md
|
|
36
|
-
- Identify Apex classes and triggers as entrypoints in entrypoints.md
|
|
37
|
-
|
|
38
|
-
### ai-first-cli
|
|
39
|
-
|
|
40
|
-
- **Type:** supported
|
|
41
|
-
- **Index DB:** No
|
|
42
|
-
- **Model Scores:**
|
|
43
|
-
- Kimi K2.5: 2.25/5
|
|
44
|
-
- GLM 5: 3.25/5
|
|
45
|
-
- MiniMax 2.7: 3.25/5
|
|
46
|
-
- **Top Improvements:**
|
|
47
|
-
- Refactor architecture.md to group src/ into functional modules (Commands, Adapters, Parsers, Indexer) instead of listing every file as a module
|
|
48
|
-
- Add explicit 'What This Project Does' overview explaining the AI context generation pipeline
|
|
49
|
-
- Separate test-projects fixtures from source analysis to prevent 684 fixture files from obscuring 63 actual source files
|
|
50
|
-
- Fix architecture detection to ignore root-level documentation files and focus on actual source directories.
|
|
51
|
-
- Implement dependency parsing to correctly identify and list key libraries and testing frameworks.
|
|
52
|
-
|
|
53
|
-
### express-api
|
|
54
|
-
|
|
55
|
-
- **Type:** supported
|
|
56
|
-
- **Index DB:** Yes
|
|
57
|
-
- **Model Scores:**
|
|
58
|
-
- Kimi K2.5: 2.8/5
|
|
59
|
-
- GLM 5: 3.5/5
|
|
60
|
-
- MiniMax 2.7: 2.5/5
|
|
61
|
-
- **Top Improvements:**
|
|
62
|
-
- Fix critical inaccuracies: remove 'Contains 0 files' entries and correct architecture pattern (remove Microservices)
|
|
63
|
-
- Add API contract specifications including endpoints, methods, and data models/schemas
|
|
64
|
-
- Include actual code interfaces or summaries for key files (controllers/services) rather than just directory listings
|
|
65
|
-
- Fix 'Contains 0 files' entries to describe actual file responsibilities (index.js is main entry point, package.json defines dependencies and scripts)
|
|
66
|
-
- Add missing conventions.md and ai_rules.md files that are referenced in ai_context.md
|
|
67
|
-
|
|
68
|
-
### nestjs-backend
|
|
69
|
-
|
|
70
|
-
- **Type:** supported
|
|
71
|
-
- **Index DB:** Yes
|
|
72
|
-
- **Model Scores:**
|
|
73
|
-
- Kimi K2.5: 2.8/5
|
|
74
|
-
- GLM 5: 2.75/5
|
|
75
|
-
- MiniMax 2.7: 2.7/5
|
|
76
|
-
- **Top Improvements:**
|
|
77
|
-
- Correct framework detection to NestJS with Modular architecture pattern
|
|
78
|
-
- Document API endpoints and authentication flows from the indexed controller files
|
|
79
|
-
- Add separation between AI metadata (ai/) and source code analysis in architectural descriptions
|
|
80
|
-
- Fix framework detection to properly identify NestJS and include its patterns/decorators in documentation
|
|
81
|
-
- Replace vague 'Contains X files' module descriptions with actual responsibilities and key exports
|
|
82
|
-
|
|
83
|
-
### python-cli
|
|
84
|
-
|
|
85
|
-
- **Type:** supported
|
|
86
|
-
- **Index DB:** Yes
|
|
87
|
-
- **Model Scores:**
|
|
88
|
-
- Kimi K2.5: 2.25/5
|
|
89
|
-
- GLM 5: 2.75/5
|
|
90
|
-
- MiniMax 2.7: 2/5
|
|
91
|
-
- **Top Improvements:**
|
|
92
|
-
- Fix critical architecture classification: distinguish files from directories and map MVC pattern to actual codebase components (cli commands as controllers)
|
|
93
|
-
- Populate entrypoints.md with actual function signatures, CLI command names, and registration patterns from main.py
|
|
94
|
-
- Add project-specific AI instructions: exact steps to add commands, extend Task model, and use the repository pattern
|
|
95
|
-
- Populate entrypoints.md with the main execution path and CLI usage examples.
|
|
96
|
-
- Enhance tech_stack.md to detect imported libraries (e.g., argparse, json) instead of reporting 'None detected'.
|
|
97
|
-
|
|
98
|
-
### spring-boot-app
|
|
99
|
-
|
|
100
|
-
- **Type:** supported
|
|
101
|
-
- **Index DB:** Yes
|
|
102
|
-
- **Model Scores:**
|
|
103
|
-
- Kimi K2.5: 2.25/5
|
|
104
|
-
- GLM 5: 3/5
|
|
105
|
-
- MiniMax 2.7: 2.5/5
|
|
106
|
-
- **Top Improvements:**
|
|
107
|
-
- Fix Spring Boot framework detection and correct architecture to Layered pattern
|
|
108
|
-
- Populate entrypoints.md with DemoApplication main class and all REST controller endpoints
|
|
109
|
-
- Analyze and document JPA entities (Post, User, Comment) and their relationships in features/
|
|
110
|
-
- Detect Spring Boot framework to ensure correct code generation
|
|
111
|
-
- Populate entrypoints.md with the main application class and controllers
|
|
112
|
-
|
|
113
|
-
### android-kotlin-app
|
|
114
|
-
|
|
115
|
-
- **Type:** unsupported
|
|
116
|
-
- **Index DB:** No
|
|
117
|
-
- **Model Scores:**
|
|
118
|
-
- Kimi K2.5: 2.5/5
|
|
119
|
-
- GLM 5: 3/5
|
|
120
|
-
- MiniMax 2.7: 1.5/5
|
|
121
|
-
- **Top Improvements:**
|
|
122
|
-
- Detect and index standard Android project files (manifest, build configs, resources) that appear to be missing
|
|
123
|
-
- Populate entrypoints with actual Android components and their intents/lifecycles
|
|
124
|
-
- Consolidate redundant descriptions and remove empty sections to optimize token usage for actionable technical details
|
|
125
|
-
- Detect Android framework and Gradle build system to populate tech_stack.md.
|
|
126
|
-
- Populate entrypoints.md with the main Activity and Application class.
|
|
127
|
-
|
|
128
|
-
### ios-swift-app
|
|
129
|
-
|
|
130
|
-
- **Type:** unsupported
|
|
131
|
-
- **Index DB:** No
|
|
132
|
-
- **Model Scores:**
|
|
133
|
-
- Kimi K2.5: 2.3/5
|
|
134
|
-
- GLM 5: 3/5
|
|
135
|
-
- MiniMax 2.7: 2.75/5
|
|
136
|
-
- **Top Improvements:**
|
|
137
|
-
- Validate dependencies against actual repo contents (remove phantom service/model/util layers)
|
|
138
|
-
- Include actual source code snippets or struct definitions from ContentView.swift
|
|
139
|
-
- Consolidate 6 fragmented files into 2-3 focused documents (overview, architecture, conventions)
|
|
140
|
-
- Remove hallucinated dependencies (service, model, util) from architecture.md as they do not exist in the repo map
|
|
141
|
-
- Detect and list SwiftUI as the framework (inferred from ContentView.swift) instead of 'None detected'
|
|
142
|
-
|
|
143
|
-
### go-microservice
|
|
144
|
-
|
|
145
|
-
- **Type:** unsupported
|
|
146
|
-
- **Index DB:** No
|
|
147
|
-
- **Model Scores:**
|
|
148
|
-
- Kimi K2.5: 1.75/5
|
|
149
|
-
- GLM 5: 2.75/5
|
|
150
|
-
- MiniMax 2.7: 1.5/5
|
|
151
|
-
- **Top Improvements:**
|
|
152
|
-
- Extract and document actual code content (functions, types, imports) from main.go instead of just counting it
|
|
153
|
-
- Fix factual errors: correct Go naming conventions (snake_case), remove semicolon requirement, fix 'contains 0 files' logic
|
|
154
|
-
- Populate entrypoints.md with service endpoints, ports, and request handlers, or analyze go.mod to detect actual frameworks used
|
|
155
|
-
- Populate entrypoints.md with specific run/build commands for the Go application.
|
|
156
|
-
- Fix architecture.md to correctly identify main.go as a file, not a container, and remove confusing '0 files' descriptions.
|
|
157
|
-
|
|
158
|
-
### rust-cli
|
|
159
|
-
|
|
160
|
-
- **Type:** unsupported
|
|
161
|
-
- **Index DB:** No
|
|
162
|
-
- **Model Scores:**
|
|
163
|
-
- Kimi K2.5: 1.8/5
|
|
164
|
-
- GLM 5: 3/5
|
|
165
|
-
- MiniMax 2.7: 1.5/5
|
|
166
|
-
- **Top Improvements:**
|
|
167
|
-
- Parse and include main.rs content (functions, structs, CLI args) to enable code generation
|
|
168
|
-
- Add Cargo.toml analysis with dependencies and feature flags critical for Rust development
|
|
169
|
-
- Consolidate fragmented files and remove empty placeholders to reduce context window waste
|
|
170
|
-
- Fix incorrect file naming convention (camelCase -> snake_case)
|
|
171
|
-
- Detect and include Cargo.toml and cargo package manager
|
|
172
|
-
|
|
173
|
-
### php-vanilla
|
|
174
|
-
|
|
175
|
-
- **Type:** unsupported
|
|
176
|
-
- **Index DB:** No
|
|
177
|
-
- **Model Scores:**
|
|
178
|
-
- Kimi K2.5: 2.2/5
|
|
179
|
-
- GLM 5: 3.75/5
|
|
180
|
-
- MiniMax 2.7: 1.5/5
|
|
181
|
-
- **Top Improvements:**
|
|
182
|
-
- Include actual source code content or detailed API summary of index.php
|
|
183
|
-
- Remove incorrect statements about file contents and empty generic sections
|
|
184
|
-
- Add functional description of application purpose and behavior
|
|
185
|
-
- Populate entrypoints.md to identify index.php as the primary entry point.
|
|
186
|
-
- Refine architecture.md to describe file responsibilities rather than stating 'Contains 0 files'.
|
|
187
|
-
|
|
188
|
-
## Cross-Project Analysis
|
|
189
|
-
|
|
190
|
-
### 🎯 Priority Projects (Salesforce)
|
|
191
|
-
- Average score: 2.0
|
|
192
|
-
- Key findings: See detailed section above
|
|
193
|
-
- Salesforce-specific insights: Apex classes, triggers, and SObject metadata handling
|
|
194
|
-
|
|
195
|
-
### Supported Projects
|
|
196
|
-
- Average score: 2.7
|
|
197
|
-
- Common issues: None
|
|
198
|
-
|
|
199
|
-
### Unsupported Projects
|
|
200
|
-
- Average score: 2.3
|
|
201
|
-
- Common issues: None
|
|
202
|
-
|
|
203
|
-
### Key Insights
|
|
204
|
-
1. **Salesforce Priority**: Detailed analysis of Apex, triggers, and metadata
|
|
205
|
-
2. Index DB impact on quality: Projects with Index DB show...
|
|
206
|
-
3. Unsupported projects: Generic analysis provides value but lacks framework-specific insights
|