archicore 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.
- package/README.md +530 -0
- package/dist/analyzers/dead-code.d.ts +95 -0
- package/dist/analyzers/dead-code.js +327 -0
- package/dist/analyzers/duplication.d.ts +90 -0
- package/dist/analyzers/duplication.js +344 -0
- package/dist/analyzers/security.d.ts +79 -0
- package/dist/analyzers/security.js +484 -0
- package/dist/architecture/index.d.ts +35 -0
- package/dist/architecture/index.js +249 -0
- package/dist/cli/commands/analyzers.d.ts +6 -0
- package/dist/cli/commands/analyzers.js +431 -0
- package/dist/cli/commands/export.d.ts +6 -0
- package/dist/cli/commands/export.js +78 -0
- package/dist/cli/commands/index.d.ts +8 -0
- package/dist/cli/commands/index.js +8 -0
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.js +140 -0
- package/dist/cli/commands/interactive.d.ts +7 -0
- package/dist/cli/commands/interactive.js +522 -0
- package/dist/cli/commands/projects.d.ts +6 -0
- package/dist/cli/commands/projects.js +249 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/ui/box.d.ts +17 -0
- package/dist/cli/ui/box.js +62 -0
- package/dist/cli/ui/colors.d.ts +49 -0
- package/dist/cli/ui/colors.js +86 -0
- package/dist/cli/ui/index.d.ts +9 -0
- package/dist/cli/ui/index.js +9 -0
- package/dist/cli/ui/prompt.d.ts +34 -0
- package/dist/cli/ui/prompt.js +122 -0
- package/dist/cli/ui/spinner.d.ts +29 -0
- package/dist/cli/ui/spinner.js +80 -0
- package/dist/cli/ui/table.d.ts +33 -0
- package/dist/cli/ui/table.js +84 -0
- package/dist/cli/utils/config.d.ts +23 -0
- package/dist/cli/utils/config.js +73 -0
- package/dist/cli/utils/index.d.ts +6 -0
- package/dist/cli/utils/index.js +6 -0
- package/dist/cli/utils/session.d.ts +27 -0
- package/dist/cli/utils/session.js +117 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +295 -0
- package/dist/code-index/ast-parser.d.ts +16 -0
- package/dist/code-index/ast-parser.js +330 -0
- package/dist/code-index/dependency-graph.d.ts +16 -0
- package/dist/code-index/dependency-graph.js +161 -0
- package/dist/code-index/index.d.ts +44 -0
- package/dist/code-index/index.js +124 -0
- package/dist/code-index/symbol-extractor.d.ts +13 -0
- package/dist/code-index/symbol-extractor.js +150 -0
- package/dist/export/index.d.ts +92 -0
- package/dist/export/index.js +676 -0
- package/dist/github/github-service.d.ts +146 -0
- package/dist/github/github-service.js +609 -0
- package/dist/impact-engine/index.d.ts +25 -0
- package/dist/impact-engine/index.js +284 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +149 -0
- package/dist/metrics/index.d.ts +136 -0
- package/dist/metrics/index.js +525 -0
- package/dist/orchestrator/deepseek-optimizer.d.ts +67 -0
- package/dist/orchestrator/deepseek-optimizer.js +320 -0
- package/dist/orchestrator/index.d.ts +34 -0
- package/dist/orchestrator/index.js +305 -0
- package/dist/pr-guardian/index.d.ts +143 -0
- package/dist/pr-guardian/index.js +553 -0
- package/dist/refactoring/index.d.ts +108 -0
- package/dist/refactoring/index.js +580 -0
- package/dist/rules-engine/index.d.ts +129 -0
- package/dist/rules-engine/index.js +482 -0
- package/dist/semantic-memory/embedding-service.d.ts +24 -0
- package/dist/semantic-memory/embedding-service.js +120 -0
- package/dist/semantic-memory/index.d.ts +45 -0
- package/dist/semantic-memory/index.js +206 -0
- package/dist/semantic-memory/vector-store.d.ts +27 -0
- package/dist/semantic-memory/vector-store.js +166 -0
- package/dist/server/index.d.ts +28 -0
- package/dist/server/index.js +141 -0
- package/dist/server/middleware/api-auth.d.ts +43 -0
- package/dist/server/middleware/api-auth.js +256 -0
- package/dist/server/routes/admin.d.ts +5 -0
- package/dist/server/routes/admin.js +123 -0
- package/dist/server/routes/api.d.ts +7 -0
- package/dist/server/routes/api.js +362 -0
- package/dist/server/routes/auth.d.ts +16 -0
- package/dist/server/routes/auth.js +191 -0
- package/dist/server/routes/developer.d.ts +8 -0
- package/dist/server/routes/developer.js +439 -0
- package/dist/server/routes/github.d.ts +7 -0
- package/dist/server/routes/github.js +495 -0
- package/dist/server/routes/upload.d.ts +7 -0
- package/dist/server/routes/upload.js +196 -0
- package/dist/server/services/api-key-service.d.ts +81 -0
- package/dist/server/services/api-key-service.js +281 -0
- package/dist/server/services/auth-service.d.ts +40 -0
- package/dist/server/services/auth-service.js +315 -0
- package/dist/server/services/project-service.d.ts +123 -0
- package/dist/server/services/project-service.js +533 -0
- package/dist/server/services/token-service.d.ts +107 -0
- package/dist/server/services/token-service.js +416 -0
- package/dist/server/services/upload-service.d.ts +93 -0
- package/dist/server/services/upload-service.js +464 -0
- package/dist/types/api.d.ts +188 -0
- package/dist/types/api.js +86 -0
- package/dist/types/github.d.ts +335 -0
- package/dist/types/github.js +5 -0
- package/dist/types/index.d.ts +265 -0
- package/dist/types/index.js +32 -0
- package/dist/types/user.d.ts +69 -0
- package/dist/types/user.js +42 -0
- package/dist/utils/file-utils.d.ts +20 -0
- package/dist/utils/file-utils.js +163 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.js +41 -0
- package/dist/watcher/index.d.ts +125 -0
- package/dist/watcher/index.js +397 -0
- package/package.json +71 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Change Impact Engine
|
|
3
|
+
*
|
|
4
|
+
* Анализ влияния изменений на кодовую базу:
|
|
5
|
+
* - Определение затронутых компонентов
|
|
6
|
+
* - Оценка рисков
|
|
7
|
+
* - Генерация рекомендаций
|
|
8
|
+
* - Построение графа влияния
|
|
9
|
+
*/
|
|
10
|
+
import { Logger } from '../utils/logger.js';
|
|
11
|
+
export class ImpactEngine {
|
|
12
|
+
analyzeChange(change, graph, symbols, architecture) {
|
|
13
|
+
Logger.progress(`Analyzing impact of change: ${change.description}`);
|
|
14
|
+
const affectedNodes = this.findAffectedNodes(change, graph, symbols);
|
|
15
|
+
const risks = this.assessRisks(change, affectedNodes, architecture);
|
|
16
|
+
const recommendations = this.generateRecommendations(change, affectedNodes, risks);
|
|
17
|
+
const impactGraph = this.buildImpactGraph(change, affectedNodes, graph);
|
|
18
|
+
Logger.success(`Impact analysis complete: ${affectedNodes.length} nodes affected`);
|
|
19
|
+
return {
|
|
20
|
+
change,
|
|
21
|
+
affectedNodes,
|
|
22
|
+
risks,
|
|
23
|
+
recommendations,
|
|
24
|
+
impactGraph
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
findAffectedNodes(change, graph, symbols) {
|
|
28
|
+
const affected = [];
|
|
29
|
+
const visited = new Set();
|
|
30
|
+
const changedNodes = this.getChangedNodes(change, graph, symbols);
|
|
31
|
+
for (const nodeId of changedNodes) {
|
|
32
|
+
this.traverseDependents(nodeId, graph, affected, visited, 0);
|
|
33
|
+
}
|
|
34
|
+
affected.sort((a, b) => {
|
|
35
|
+
const levelOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
36
|
+
return levelOrder[a.impactLevel] - levelOrder[b.impactLevel];
|
|
37
|
+
});
|
|
38
|
+
return affected;
|
|
39
|
+
}
|
|
40
|
+
getChangedNodes(change, graph, symbols) {
|
|
41
|
+
const nodes = new Set();
|
|
42
|
+
for (const file of change.files) {
|
|
43
|
+
const node = graph.nodes.get(file);
|
|
44
|
+
if (node) {
|
|
45
|
+
nodes.add(node.id);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const symbolName of change.symbols) {
|
|
49
|
+
for (const symbol of symbols.values()) {
|
|
50
|
+
if (symbol.name === symbolName) {
|
|
51
|
+
nodes.add(symbol.id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return nodes;
|
|
56
|
+
}
|
|
57
|
+
traverseDependents(nodeId, graph, affected, visited, distance, maxDistance = 5) {
|
|
58
|
+
if (visited.has(nodeId) || distance > maxDistance) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
visited.add(nodeId);
|
|
62
|
+
const node = graph.nodes.get(nodeId);
|
|
63
|
+
if (!node)
|
|
64
|
+
return;
|
|
65
|
+
const impactLevel = this.calculateImpactLevel(distance, node.type);
|
|
66
|
+
affected.push({
|
|
67
|
+
id: nodeId,
|
|
68
|
+
name: node.name,
|
|
69
|
+
type: node.type,
|
|
70
|
+
filePath: node.filePath,
|
|
71
|
+
impactLevel,
|
|
72
|
+
reason: this.generateImpactReason(distance, node.type),
|
|
73
|
+
distance
|
|
74
|
+
});
|
|
75
|
+
const dependents = this.findDependents(nodeId, graph);
|
|
76
|
+
for (const dependent of dependents) {
|
|
77
|
+
this.traverseDependents(dependent, graph, affected, visited, distance + 1, maxDistance);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
findDependents(nodeId, graph) {
|
|
81
|
+
const dependents = [];
|
|
82
|
+
for (const [from, edges] of graph.edges) {
|
|
83
|
+
for (const edge of edges) {
|
|
84
|
+
if (edge.to === nodeId) {
|
|
85
|
+
dependents.push(from);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return dependents;
|
|
90
|
+
}
|
|
91
|
+
calculateImpactLevel(distance, nodeType) {
|
|
92
|
+
if (distance === 0)
|
|
93
|
+
return 'critical';
|
|
94
|
+
if (distance === 1 && nodeType === 'file')
|
|
95
|
+
return 'high';
|
|
96
|
+
if (distance === 1)
|
|
97
|
+
return 'high';
|
|
98
|
+
if (distance === 2)
|
|
99
|
+
return 'medium';
|
|
100
|
+
return 'low';
|
|
101
|
+
}
|
|
102
|
+
generateImpactReason(distance, _nodeType) {
|
|
103
|
+
if (distance === 0)
|
|
104
|
+
return 'Directly modified';
|
|
105
|
+
if (distance === 1)
|
|
106
|
+
return 'Direct dependency';
|
|
107
|
+
if (distance === 2)
|
|
108
|
+
return 'Indirect dependency (2 levels)';
|
|
109
|
+
return `Indirect dependency (${distance} levels)`;
|
|
110
|
+
}
|
|
111
|
+
assessRisks(change, affectedNodes, _architecture) {
|
|
112
|
+
const risks = [];
|
|
113
|
+
const criticalNodes = affectedNodes.filter(n => n.impactLevel === 'critical');
|
|
114
|
+
const highImpactNodes = affectedNodes.filter(n => n.impactLevel === 'high');
|
|
115
|
+
if (criticalNodes.length > 10) {
|
|
116
|
+
risks.push({
|
|
117
|
+
id: 'wide-impact',
|
|
118
|
+
severity: 'high',
|
|
119
|
+
category: 'breaking_change',
|
|
120
|
+
description: `Change affects ${criticalNodes.length} critical components`,
|
|
121
|
+
affectedComponents: criticalNodes.map(n => n.name),
|
|
122
|
+
mitigation: 'Consider breaking into smaller changes'
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (change.type === 'delete') {
|
|
126
|
+
risks.push({
|
|
127
|
+
id: 'deletion-risk',
|
|
128
|
+
severity: 'critical',
|
|
129
|
+
category: 'breaking_change',
|
|
130
|
+
description: 'Deletion may break dependent components',
|
|
131
|
+
affectedComponents: affectedNodes.map(n => n.name),
|
|
132
|
+
mitigation: 'Ensure all dependencies are updated or removed'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (change.type === 'modify' && highImpactNodes.length > 0) {
|
|
136
|
+
risks.push({
|
|
137
|
+
id: 'api-change',
|
|
138
|
+
severity: 'high',
|
|
139
|
+
category: 'compatibility',
|
|
140
|
+
description: 'Modification may break API contracts',
|
|
141
|
+
affectedComponents: highImpactNodes.map(n => n.name),
|
|
142
|
+
mitigation: 'Review and update all API consumers'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const coreFiles = affectedNodes.filter(n => n.filePath.includes('/core/') || n.filePath.includes('/kernel/'));
|
|
146
|
+
if (coreFiles.length > 0) {
|
|
147
|
+
risks.push({
|
|
148
|
+
id: 'core-system-risk',
|
|
149
|
+
severity: 'critical',
|
|
150
|
+
category: 'breaking_change',
|
|
151
|
+
description: 'Change affects core system components',
|
|
152
|
+
affectedComponents: coreFiles.map(n => n.name),
|
|
153
|
+
mitigation: 'Thorough testing required, consider staged rollout'
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return risks;
|
|
157
|
+
}
|
|
158
|
+
generateRecommendations(change, affectedNodes, risks) {
|
|
159
|
+
const recommendations = [];
|
|
160
|
+
recommendations.push({
|
|
161
|
+
type: 'review',
|
|
162
|
+
priority: 'critical',
|
|
163
|
+
description: 'Review all affected components',
|
|
164
|
+
details: `${affectedNodes.length} components will be affected by this change`
|
|
165
|
+
});
|
|
166
|
+
const criticalNodes = affectedNodes.filter(n => n.impactLevel === 'critical');
|
|
167
|
+
if (criticalNodes.length > 0) {
|
|
168
|
+
recommendations.push({
|
|
169
|
+
type: 'test',
|
|
170
|
+
priority: 'critical',
|
|
171
|
+
description: 'Test critical components',
|
|
172
|
+
details: `Focus on: ${criticalNodes.slice(0, 5).map(n => n.name).join(', ')}`
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const highRisks = risks.filter(r => r.severity === 'critical' || r.severity === 'high');
|
|
176
|
+
if (highRisks.length > 0) {
|
|
177
|
+
recommendations.push({
|
|
178
|
+
type: 'check',
|
|
179
|
+
priority: 'critical',
|
|
180
|
+
description: 'Address high-severity risks',
|
|
181
|
+
details: highRisks.map(r => r.description).join('; ')
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (affectedNodes.some(n => n.filePath.includes('test'))) {
|
|
185
|
+
recommendations.push({
|
|
186
|
+
type: 'test',
|
|
187
|
+
priority: 'high',
|
|
188
|
+
description: 'Update affected tests',
|
|
189
|
+
details: 'Test files detected in affected nodes'
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (change.type === 'refactor') {
|
|
193
|
+
recommendations.push({
|
|
194
|
+
type: 'refactor',
|
|
195
|
+
priority: 'medium',
|
|
196
|
+
description: 'Consider incremental refactoring',
|
|
197
|
+
details: 'Break into smaller, safer changes'
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return recommendations;
|
|
201
|
+
}
|
|
202
|
+
buildImpactGraph(_change, affectedNodes, graph) {
|
|
203
|
+
const impactGraph = {
|
|
204
|
+
nodes: new Map(),
|
|
205
|
+
edges: []
|
|
206
|
+
};
|
|
207
|
+
for (const affected of affectedNodes) {
|
|
208
|
+
const node = {
|
|
209
|
+
id: affected.id,
|
|
210
|
+
name: affected.name,
|
|
211
|
+
impactLevel: affected.impactLevel,
|
|
212
|
+
metadata: {
|
|
213
|
+
type: affected.type,
|
|
214
|
+
filePath: affected.filePath,
|
|
215
|
+
distance: affected.distance,
|
|
216
|
+
reason: affected.reason
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
impactGraph.nodes.set(affected.id, node);
|
|
220
|
+
}
|
|
221
|
+
for (const affected of affectedNodes) {
|
|
222
|
+
const edges = graph.edges.get(affected.id) || [];
|
|
223
|
+
for (const edge of edges) {
|
|
224
|
+
if (impactGraph.nodes.has(edge.to)) {
|
|
225
|
+
impactGraph.edges.push({
|
|
226
|
+
from: affected.id,
|
|
227
|
+
to: edge.to,
|
|
228
|
+
reason: `Depends on via ${edge.type}`
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return impactGraph;
|
|
234
|
+
}
|
|
235
|
+
generateReport(impact) {
|
|
236
|
+
let report = `# Impact Analysis: ${impact.change.description}\n\n`;
|
|
237
|
+
report += `## Summary\n\n`;
|
|
238
|
+
report += `- **Change Type:** ${impact.change.type}\n`;
|
|
239
|
+
report += `- **Affected Files:** ${impact.change.files.length}\n`;
|
|
240
|
+
report += `- **Affected Components:** ${impact.affectedNodes.length}\n`;
|
|
241
|
+
report += `- **Risks Identified:** ${impact.risks.length}\n\n`;
|
|
242
|
+
report += `## Affected Components\n\n`;
|
|
243
|
+
const byLevel = this.groupByImpactLevel(impact.affectedNodes);
|
|
244
|
+
for (const [level, nodes] of Object.entries(byLevel)) {
|
|
245
|
+
if (nodes.length > 0) {
|
|
246
|
+
report += `### ${level.toUpperCase()} Impact (${nodes.length})\n\n`;
|
|
247
|
+
for (const node of nodes.slice(0, 10)) {
|
|
248
|
+
report += `- **${node.name}** (${node.filePath})\n`;
|
|
249
|
+
report += ` - ${node.reason}\n`;
|
|
250
|
+
}
|
|
251
|
+
if (nodes.length > 10) {
|
|
252
|
+
report += `\n... and ${nodes.length - 10} more\n`;
|
|
253
|
+
}
|
|
254
|
+
report += '\n';
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
report += `## Risks\n\n`;
|
|
258
|
+
for (const risk of impact.risks) {
|
|
259
|
+
report += `### ${risk.severity.toUpperCase()}: ${risk.description}\n`;
|
|
260
|
+
report += `**Category:** ${risk.category}\n`;
|
|
261
|
+
if (risk.mitigation) {
|
|
262
|
+
report += `**Mitigation:** ${risk.mitigation}\n`;
|
|
263
|
+
}
|
|
264
|
+
report += '\n';
|
|
265
|
+
}
|
|
266
|
+
report += `## Recommendations\n\n`;
|
|
267
|
+
for (const rec of impact.recommendations) {
|
|
268
|
+
report += `- **[${rec.priority.toUpperCase()}]** ${rec.description}\n`;
|
|
269
|
+
if (rec.details) {
|
|
270
|
+
report += ` ${rec.details}\n`;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return report;
|
|
274
|
+
}
|
|
275
|
+
groupByImpactLevel(nodes) {
|
|
276
|
+
return {
|
|
277
|
+
critical: nodes.filter(n => n.impactLevel === 'critical'),
|
|
278
|
+
high: nodes.filter(n => n.impactLevel === 'high'),
|
|
279
|
+
medium: nodes.filter(n => n.impactLevel === 'medium'),
|
|
280
|
+
low: nodes.filter(n => n.impactLevel === 'low')
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIArhitector - AI Software Architect System
|
|
3
|
+
*
|
|
4
|
+
* Главный класс, объединяющий все модули системы
|
|
5
|
+
*/
|
|
6
|
+
import { Change, ChangeImpact, LLMConfig, SemanticSearchResult, DependencyGraph } from './types/index.js';
|
|
7
|
+
export interface AIArhitectorConfig {
|
|
8
|
+
rootDir: string;
|
|
9
|
+
llm: LLMConfig;
|
|
10
|
+
vectorStore: {
|
|
11
|
+
url: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
collectionName: string;
|
|
14
|
+
};
|
|
15
|
+
architectureConfigPath?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class AIArhitector {
|
|
18
|
+
private codeIndex;
|
|
19
|
+
private semanticMemory;
|
|
20
|
+
private architecture;
|
|
21
|
+
private impactEngine;
|
|
22
|
+
private orchestrator;
|
|
23
|
+
private config;
|
|
24
|
+
private initialized;
|
|
25
|
+
constructor(config: AIArhitectorConfig);
|
|
26
|
+
initialize(): Promise<void>;
|
|
27
|
+
analyzeChange(change: Change): Promise<ChangeImpact>;
|
|
28
|
+
searchCode(query: string, limit?: number): Promise<SemanticSearchResult[]>;
|
|
29
|
+
askQuestion(question: string): Promise<string>;
|
|
30
|
+
suggestRefactoring(code: string, goal: string): Promise<string>;
|
|
31
|
+
reviewCode(code: string, changedFiles: string[]): Promise<string>;
|
|
32
|
+
generateDocumentation(): Promise<string>;
|
|
33
|
+
getDependencyGraph(): DependencyGraph | null;
|
|
34
|
+
getArchitectureModel(): import("./types/index.js").ArchitectureModel;
|
|
35
|
+
getStatistics(): {
|
|
36
|
+
codeIndex: {
|
|
37
|
+
totalFiles: number;
|
|
38
|
+
totalSymbols: number;
|
|
39
|
+
totalNodes: number;
|
|
40
|
+
totalEdges: number;
|
|
41
|
+
symbolsByKind: Record<string, number>;
|
|
42
|
+
};
|
|
43
|
+
semanticMemory: Promise<{
|
|
44
|
+
name: string;
|
|
45
|
+
vectorsCount: number;
|
|
46
|
+
pointsCount: number | null | undefined;
|
|
47
|
+
status: "green" | "yellow" | "grey" | "red";
|
|
48
|
+
} | null>;
|
|
49
|
+
};
|
|
50
|
+
reindexFile(filePath: string): Promise<void>;
|
|
51
|
+
private ensureInitialized;
|
|
52
|
+
}
|
|
53
|
+
export * from './types/index.js';
|
|
54
|
+
export { CodeIndex } from './code-index/index.js';
|
|
55
|
+
export { SemanticMemory } from './semantic-memory/index.js';
|
|
56
|
+
export { ArchitectureKnowledge } from './architecture/index.js';
|
|
57
|
+
export { ImpactEngine } from './impact-engine/index.js';
|
|
58
|
+
export { LLMOrchestrator } from './orchestrator/index.js';
|
|
59
|
+
export { DeepSeekOptimizer } from './orchestrator/deepseek-optimizer.js';
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIArhitector - AI Software Architect System
|
|
3
|
+
*
|
|
4
|
+
* Главный класс, объединяющий все модули системы
|
|
5
|
+
*/
|
|
6
|
+
import { CodeIndex } from './code-index/index.js';
|
|
7
|
+
import { SemanticMemory } from './semantic-memory/index.js';
|
|
8
|
+
import { ArchitectureKnowledge } from './architecture/index.js';
|
|
9
|
+
import { ImpactEngine } from './impact-engine/index.js';
|
|
10
|
+
import { LLMOrchestrator } from './orchestrator/index.js';
|
|
11
|
+
import { Logger } from './utils/logger.js';
|
|
12
|
+
import { config } from 'dotenv';
|
|
13
|
+
config();
|
|
14
|
+
export class AIArhitector {
|
|
15
|
+
codeIndex;
|
|
16
|
+
semanticMemory;
|
|
17
|
+
architecture;
|
|
18
|
+
impactEngine;
|
|
19
|
+
orchestrator;
|
|
20
|
+
config;
|
|
21
|
+
initialized = false;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.codeIndex = new CodeIndex();
|
|
25
|
+
this.semanticMemory = new SemanticMemory({ provider: config.llm.provider }, config.vectorStore);
|
|
26
|
+
this.architecture = new ArchitectureKnowledge(config.architectureConfigPath || '.aiarhitector/architecture.json');
|
|
27
|
+
this.impactEngine = new ImpactEngine();
|
|
28
|
+
this.orchestrator = new LLMOrchestrator(config.llm);
|
|
29
|
+
Logger.info('AIArhitector initialized');
|
|
30
|
+
}
|
|
31
|
+
async initialize() {
|
|
32
|
+
if (this.initialized) {
|
|
33
|
+
Logger.warn('Already initialized');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
Logger.info('Initializing AIArhitector...');
|
|
37
|
+
await this.codeIndex.indexProject(this.config.rootDir);
|
|
38
|
+
await this.semanticMemory.initialize();
|
|
39
|
+
await this.semanticMemory.indexSymbols(this.codeIndex.getSymbols(), this.codeIndex.getASTs());
|
|
40
|
+
await this.architecture.load();
|
|
41
|
+
this.initialized = true;
|
|
42
|
+
Logger.success('AIArhitector ready!');
|
|
43
|
+
}
|
|
44
|
+
async analyzeChange(change) {
|
|
45
|
+
this.ensureInitialized();
|
|
46
|
+
Logger.info(`Analyzing change: ${change.description}`);
|
|
47
|
+
const graph = this.codeIndex.getGraph();
|
|
48
|
+
if (!graph) {
|
|
49
|
+
throw new Error('Dependency graph not built');
|
|
50
|
+
}
|
|
51
|
+
const impact = this.impactEngine.analyzeChange(change, graph, this.codeIndex.getSymbols(), this.architecture.getModel());
|
|
52
|
+
const semanticContext = await this.semanticMemory.searchByQuery(change.description, 5);
|
|
53
|
+
const llmAnalysis = await this.orchestrator.analyzeImpact(impact, {
|
|
54
|
+
architecture: this.architecture.getModel(),
|
|
55
|
+
semanticMemory: semanticContext,
|
|
56
|
+
codeIndex: graph,
|
|
57
|
+
recentChanges: [change]
|
|
58
|
+
});
|
|
59
|
+
Logger.info('LLM Analysis:\n' + llmAnalysis);
|
|
60
|
+
return impact;
|
|
61
|
+
}
|
|
62
|
+
async searchCode(query, limit = 10) {
|
|
63
|
+
this.ensureInitialized();
|
|
64
|
+
return await this.semanticMemory.searchByQuery(query, limit);
|
|
65
|
+
}
|
|
66
|
+
async askQuestion(question) {
|
|
67
|
+
this.ensureInitialized();
|
|
68
|
+
const semanticContext = await this.semanticMemory.searchByQuery(question, 10);
|
|
69
|
+
const answer = await this.orchestrator.answerArchitecturalQuestion(question, {
|
|
70
|
+
architecture: this.architecture.getModel(),
|
|
71
|
+
semanticMemory: semanticContext,
|
|
72
|
+
codeIndex: this.codeIndex.getGraph() || undefined
|
|
73
|
+
});
|
|
74
|
+
return answer;
|
|
75
|
+
}
|
|
76
|
+
async suggestRefactoring(code, goal) {
|
|
77
|
+
this.ensureInitialized();
|
|
78
|
+
const semanticContext = await this.semanticMemory.searchSimilarCode(code, {}, 5);
|
|
79
|
+
const suggestion = await this.orchestrator.suggestRefactoring(code, goal, {
|
|
80
|
+
architecture: this.architecture.getModel(),
|
|
81
|
+
semanticMemory: semanticContext
|
|
82
|
+
});
|
|
83
|
+
return suggestion;
|
|
84
|
+
}
|
|
85
|
+
async reviewCode(code, changedFiles) {
|
|
86
|
+
this.ensureInitialized();
|
|
87
|
+
const semanticContext = await this.semanticMemory.searchSimilarCode(code, {}, 5);
|
|
88
|
+
const review = await this.orchestrator.reviewCode(code, changedFiles, {
|
|
89
|
+
architecture: this.architecture.getModel(),
|
|
90
|
+
semanticMemory: semanticContext,
|
|
91
|
+
codeIndex: this.codeIndex.getGraph() || undefined
|
|
92
|
+
});
|
|
93
|
+
return review;
|
|
94
|
+
}
|
|
95
|
+
async generateDocumentation() {
|
|
96
|
+
this.ensureInitialized();
|
|
97
|
+
const graph = this.codeIndex.getGraph();
|
|
98
|
+
const stats = this.codeIndex.getStatistics();
|
|
99
|
+
const codebaseSummary = `
|
|
100
|
+
Codebase Statistics:
|
|
101
|
+
- Total Files: ${stats.totalFiles}
|
|
102
|
+
- Total Symbols: ${stats.totalSymbols}
|
|
103
|
+
- Symbols by Kind: ${JSON.stringify(stats.symbolsByKind, null, 2)}
|
|
104
|
+
|
|
105
|
+
Architecture:
|
|
106
|
+
${this.architecture.generateReport()}
|
|
107
|
+
`;
|
|
108
|
+
const docs = await this.orchestrator.generateDocumentation(codebaseSummary, {
|
|
109
|
+
architecture: this.architecture.getModel(),
|
|
110
|
+
codeIndex: graph || undefined
|
|
111
|
+
});
|
|
112
|
+
return docs;
|
|
113
|
+
}
|
|
114
|
+
getDependencyGraph() {
|
|
115
|
+
return this.codeIndex.getGraph();
|
|
116
|
+
}
|
|
117
|
+
getArchitectureModel() {
|
|
118
|
+
return this.architecture.getModel();
|
|
119
|
+
}
|
|
120
|
+
getStatistics() {
|
|
121
|
+
return {
|
|
122
|
+
codeIndex: this.codeIndex.getStatistics(),
|
|
123
|
+
semanticMemory: this.semanticMemory.getStatistics()
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async reindexFile(filePath) {
|
|
127
|
+
this.ensureInitialized();
|
|
128
|
+
await this.codeIndex.reindexFile(filePath);
|
|
129
|
+
await this.semanticMemory.deleteFile(filePath);
|
|
130
|
+
const symbols = this.codeIndex.findSymbolsInFile(filePath);
|
|
131
|
+
const asts = this.codeIndex.getASTs();
|
|
132
|
+
const fileSymbols = new Map(symbols.map(s => [s.id, s]));
|
|
133
|
+
await this.semanticMemory.indexSymbols(fileSymbols, asts);
|
|
134
|
+
Logger.success(`File reindexed: ${filePath}`);
|
|
135
|
+
}
|
|
136
|
+
ensureInitialized() {
|
|
137
|
+
if (!this.initialized) {
|
|
138
|
+
throw new Error('AIArhitector not initialized. Call initialize() first.');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export * from './types/index.js';
|
|
143
|
+
export { CodeIndex } from './code-index/index.js';
|
|
144
|
+
export { SemanticMemory } from './semantic-memory/index.js';
|
|
145
|
+
export { ArchitectureKnowledge } from './architecture/index.js';
|
|
146
|
+
export { ImpactEngine } from './impact-engine/index.js';
|
|
147
|
+
export { LLMOrchestrator } from './orchestrator/index.js';
|
|
148
|
+
export { DeepSeekOptimizer } from './orchestrator/deepseek-optimizer.js';
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Metrics Module
|
|
3
|
+
*
|
|
4
|
+
* Вычисление метрик качества кода:
|
|
5
|
+
* - Цикломатическая сложность
|
|
6
|
+
* - Когнитивная сложность
|
|
7
|
+
* - Связанность (Coupling)
|
|
8
|
+
* - Связность (Cohesion)
|
|
9
|
+
* - Maintainability Index
|
|
10
|
+
* - Lines of Code метрики
|
|
11
|
+
*/
|
|
12
|
+
import { DependencyGraph, Symbol, ASTNode } from '../types/index.js';
|
|
13
|
+
export interface FileMetrics {
|
|
14
|
+
filePath: string;
|
|
15
|
+
loc: LOCMetrics;
|
|
16
|
+
complexity: ComplexityMetrics;
|
|
17
|
+
coupling: CouplingMetrics;
|
|
18
|
+
maintainability: number;
|
|
19
|
+
issues: MetricIssue[];
|
|
20
|
+
}
|
|
21
|
+
export interface LOCMetrics {
|
|
22
|
+
total: number;
|
|
23
|
+
code: number;
|
|
24
|
+
comments: number;
|
|
25
|
+
blank: number;
|
|
26
|
+
ratio: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ComplexityMetrics {
|
|
29
|
+
cyclomatic: number;
|
|
30
|
+
cognitive: number;
|
|
31
|
+
halstead: HalsteadMetrics;
|
|
32
|
+
maxNesting: number;
|
|
33
|
+
avgFunctionComplexity: number;
|
|
34
|
+
}
|
|
35
|
+
export interface HalsteadMetrics {
|
|
36
|
+
vocabulary: number;
|
|
37
|
+
length: number;
|
|
38
|
+
volume: number;
|
|
39
|
+
difficulty: number;
|
|
40
|
+
effort: number;
|
|
41
|
+
time: number;
|
|
42
|
+
bugs: number;
|
|
43
|
+
}
|
|
44
|
+
export interface CouplingMetrics {
|
|
45
|
+
afferentCoupling: number;
|
|
46
|
+
efferentCoupling: number;
|
|
47
|
+
instability: number;
|
|
48
|
+
abstractness: number;
|
|
49
|
+
distance: number;
|
|
50
|
+
}
|
|
51
|
+
export interface MetricIssue {
|
|
52
|
+
type: 'complexity' | 'coupling' | 'size' | 'maintainability';
|
|
53
|
+
severity: 'high' | 'medium' | 'low';
|
|
54
|
+
message: string;
|
|
55
|
+
suggestion: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ProjectMetrics {
|
|
58
|
+
summary: ProjectSummary;
|
|
59
|
+
files: FileMetrics[];
|
|
60
|
+
hotspots: Hotspot[];
|
|
61
|
+
}
|
|
62
|
+
export interface ProjectSummary {
|
|
63
|
+
totalFiles: number;
|
|
64
|
+
totalLOC: number;
|
|
65
|
+
avgComplexity: number;
|
|
66
|
+
avgMaintainability: number;
|
|
67
|
+
avgCoupling: number;
|
|
68
|
+
technicalDebtHours: number;
|
|
69
|
+
grade: 'A' | 'B' | 'C' | 'D' | 'F';
|
|
70
|
+
}
|
|
71
|
+
export interface Hotspot {
|
|
72
|
+
filePath: string;
|
|
73
|
+
score: number;
|
|
74
|
+
reasons: string[];
|
|
75
|
+
}
|
|
76
|
+
export declare class MetricsCalculator {
|
|
77
|
+
private readonly COMPLEXITY_THRESHOLD;
|
|
78
|
+
private readonly COGNITIVE_THRESHOLD;
|
|
79
|
+
private readonly COUPLING_THRESHOLD;
|
|
80
|
+
private readonly LOC_THRESHOLD;
|
|
81
|
+
private readonly NESTING_THRESHOLD;
|
|
82
|
+
/**
|
|
83
|
+
* Вычислить метрики для всего проекта
|
|
84
|
+
*/
|
|
85
|
+
calculateProjectMetrics(graph: DependencyGraph, symbols: Map<string, Symbol>, fileContents: Map<string, string>, asts: Map<string, ASTNode>): Promise<ProjectMetrics>;
|
|
86
|
+
/**
|
|
87
|
+
* Вычислить метрики для одного файла
|
|
88
|
+
*/
|
|
89
|
+
calculateFileMetrics(filePath: string, content: string, ast: ASTNode | undefined, graph: DependencyGraph, symbols: Map<string, Symbol>): FileMetrics;
|
|
90
|
+
/**
|
|
91
|
+
* Подсчёт строк кода
|
|
92
|
+
*/
|
|
93
|
+
private calculateLOC;
|
|
94
|
+
/**
|
|
95
|
+
* Вычисление сложности
|
|
96
|
+
*/
|
|
97
|
+
private calculateComplexity;
|
|
98
|
+
/**
|
|
99
|
+
* Цикломатическая сложность (McCabe)
|
|
100
|
+
*/
|
|
101
|
+
private calculateCyclomaticComplexity;
|
|
102
|
+
/**
|
|
103
|
+
* Когнитивная сложность (SonarSource)
|
|
104
|
+
*/
|
|
105
|
+
private calculateCognitiveComplexity;
|
|
106
|
+
/**
|
|
107
|
+
* Halstead метрики
|
|
108
|
+
*/
|
|
109
|
+
private calculateHalsteadMetrics;
|
|
110
|
+
/**
|
|
111
|
+
* Максимальная вложенность
|
|
112
|
+
*/
|
|
113
|
+
private calculateMaxNesting;
|
|
114
|
+
/**
|
|
115
|
+
* Вычисление связанности
|
|
116
|
+
*/
|
|
117
|
+
private calculateCoupling;
|
|
118
|
+
/**
|
|
119
|
+
* Индекс поддерживаемости (Maintainability Index)
|
|
120
|
+
* Формула Microsoft: MI = MAX(0, (171 - 5.2 * ln(V) - 0.23 * G - 16.2 * ln(LOC)) * 100 / 171)
|
|
121
|
+
*/
|
|
122
|
+
private calculateMaintainability;
|
|
123
|
+
/**
|
|
124
|
+
* Выявление проблем
|
|
125
|
+
*/
|
|
126
|
+
private identifyIssues;
|
|
127
|
+
/**
|
|
128
|
+
* Сводка по проекту
|
|
129
|
+
*/
|
|
130
|
+
private calculateSummary;
|
|
131
|
+
/**
|
|
132
|
+
* Определение "горячих точек"
|
|
133
|
+
*/
|
|
134
|
+
private identifyHotspots;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=index.d.ts.map
|