archicore 0.3.6 → 0.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/dist/cli/commands/interactive.js +220 -1
- package/dist/github/github-service.d.ts +4 -4
- package/dist/github/github-service.js +29 -13
- package/dist/gitlab/gitlab-service.js +48 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +19 -9
- package/dist/orchestrator/index.js +72 -7
- package/dist/server/index.js +68 -1
- package/dist/server/routes/api.js +242 -2
- package/dist/server/routes/auth.d.ts +1 -0
- package/dist/server/routes/auth.js +11 -3
- package/dist/server/routes/gitlab.js +18 -46
- package/dist/server/routes/report-issue.js +103 -0
- package/dist/server/routes/upload.js +3 -3
- package/dist/server/services/encryption.js +20 -4
- package/dist/server/services/enterprise-indexer.d.ts +116 -0
- package/dist/server/services/enterprise-indexer.js +529 -0
- package/dist/server/services/project-service.js +14 -5
- package/dist/types/index.d.ts +9 -0
- package/dist/utils/project-analyzer.d.ts +13 -0
- package/dist/utils/project-analyzer.js +130 -0
- package/package.json +1 -1
|
@@ -420,12 +420,20 @@ export class ProjectService {
|
|
|
420
420
|
}));
|
|
421
421
|
}
|
|
422
422
|
async askArchitect(projectId, question, language = 'en') {
|
|
423
|
+
const project = this.projects.get(projectId);
|
|
424
|
+
if (!project) {
|
|
425
|
+
throw new Error(`Project not found: ${projectId}`);
|
|
426
|
+
}
|
|
423
427
|
const data = await this.getProjectData(projectId);
|
|
428
|
+
// Анализируем стек технологий проекта
|
|
429
|
+
const { analyzeProjectStack } = await import('../../utils/project-analyzer.js');
|
|
430
|
+
const projectMetadata = analyzeProjectStack(project.path);
|
|
424
431
|
// Ищем релевантный контекст (если есть семантическая память)
|
|
425
432
|
let searchResults = [];
|
|
426
433
|
if (data.semanticMemory) {
|
|
427
434
|
try {
|
|
428
|
-
|
|
435
|
+
// Увеличиваем лимит результатов поиска с 5 до 30
|
|
436
|
+
searchResults = await data.semanticMemory.searchByQuery(question, 30);
|
|
429
437
|
Logger.debug(`Semantic search returned ${searchResults.length} results`);
|
|
430
438
|
}
|
|
431
439
|
catch (err) {
|
|
@@ -435,7 +443,7 @@ export class ProjectService {
|
|
|
435
443
|
// Fallback: если семантический поиск не работает, даём контекст из графа
|
|
436
444
|
if (searchResults.length === 0 && data.graph) {
|
|
437
445
|
Logger.info('Using graph fallback for context');
|
|
438
|
-
const files = Array.from(data.graph.nodes.values()).slice(0,
|
|
446
|
+
const files = Array.from(data.graph.nodes.values()).slice(0, 30); // Увеличено с 10 до 30
|
|
439
447
|
for (const file of files) {
|
|
440
448
|
searchResults.push({
|
|
441
449
|
chunk: {
|
|
@@ -458,7 +466,7 @@ export class ProjectService {
|
|
|
458
466
|
}
|
|
459
467
|
// Добавляем информацию о символах если есть
|
|
460
468
|
if (data.symbols && data.symbols.size > 0) {
|
|
461
|
-
const symbolsList = Array.from(data.symbols.values()).slice(0,
|
|
469
|
+
const symbolsList = Array.from(data.symbols.values()).slice(0, 50); // Увеличено с 20 до 50
|
|
462
470
|
for (const sym of symbolsList) {
|
|
463
471
|
const existing = searchResults.find(r => r.chunk.metadata.filePath === sym.filePath);
|
|
464
472
|
if (existing) {
|
|
@@ -466,11 +474,12 @@ export class ProjectService {
|
|
|
466
474
|
}
|
|
467
475
|
}
|
|
468
476
|
}
|
|
469
|
-
Logger.debug(`Passing ${searchResults.length} context items to AI`);
|
|
477
|
+
Logger.debug(`Passing ${searchResults.length} context items + project metadata to AI`);
|
|
470
478
|
const answer = await data.orchestrator.answerArchitecturalQuestion(question, {
|
|
471
479
|
architecture: data.architecture.getModel(),
|
|
472
480
|
semanticMemory: searchResults,
|
|
473
|
-
language
|
|
481
|
+
language,
|
|
482
|
+
projectMetadata: projectMetadata || undefined
|
|
474
483
|
});
|
|
475
484
|
return answer;
|
|
476
485
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -218,12 +218,21 @@ export interface LLMPrompt {
|
|
|
218
218
|
user: string;
|
|
219
219
|
context?: LLMContext;
|
|
220
220
|
}
|
|
221
|
+
export interface ProjectMetadata {
|
|
222
|
+
framework?: string;
|
|
223
|
+
dependencies?: Record<string, string>;
|
|
224
|
+
devDependencies?: Record<string, string>;
|
|
225
|
+
buildTool?: string;
|
|
226
|
+
backend?: string;
|
|
227
|
+
database?: string;
|
|
228
|
+
}
|
|
221
229
|
export interface LLMContext {
|
|
222
230
|
codeIndex?: Partial<DependencyGraph>;
|
|
223
231
|
semanticMemory?: SemanticSearchResult[];
|
|
224
232
|
architecture?: Partial<ArchitectureModel>;
|
|
225
233
|
recentChanges?: Change[];
|
|
226
234
|
language?: 'en' | 'ru';
|
|
235
|
+
projectMetadata?: ProjectMetadata;
|
|
227
236
|
}
|
|
228
237
|
export interface LLMResponse {
|
|
229
238
|
content: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Analyzer - анализ package.json для определения стека технологий
|
|
3
|
+
*/
|
|
4
|
+
import { ProjectMetadata } from '../types/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Анализирует package.json проекта и определяет используемые технологии
|
|
7
|
+
*/
|
|
8
|
+
export declare function analyzeProjectStack(projectPath: string): ProjectMetadata | null;
|
|
9
|
+
/**
|
|
10
|
+
* Создает человекочитаемое описание стека проекта
|
|
11
|
+
*/
|
|
12
|
+
export declare function describeProjectStack(metadata: ProjectMetadata | null): string;
|
|
13
|
+
//# sourceMappingURL=project-analyzer.d.ts.map
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Analyzer - анализ package.json для определения стека технологий
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { Logger } from './logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Анализирует package.json проекта и определяет используемые технологии
|
|
9
|
+
*/
|
|
10
|
+
export function analyzeProjectStack(projectPath) {
|
|
11
|
+
try {
|
|
12
|
+
const packageJsonPath = join(projectPath, 'package.json');
|
|
13
|
+
if (!existsSync(packageJsonPath)) {
|
|
14
|
+
Logger.warn('package.json not found in project');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
18
|
+
const deps = packageJson.dependencies || {};
|
|
19
|
+
const devDeps = packageJson.devDependencies || {};
|
|
20
|
+
const allDeps = { ...deps, ...devDeps };
|
|
21
|
+
const metadata = {
|
|
22
|
+
dependencies: deps,
|
|
23
|
+
devDependencies: devDeps
|
|
24
|
+
};
|
|
25
|
+
// Определяем frontend framework
|
|
26
|
+
if (allDeps['vue'] || allDeps['@vue/cli']) {
|
|
27
|
+
metadata.framework = 'Vue.js';
|
|
28
|
+
}
|
|
29
|
+
else if (allDeps['react'] || allDeps['react-dom']) {
|
|
30
|
+
metadata.framework = 'React';
|
|
31
|
+
}
|
|
32
|
+
else if (allDeps['@angular/core']) {
|
|
33
|
+
metadata.framework = 'Angular';
|
|
34
|
+
}
|
|
35
|
+
else if (allDeps['svelte']) {
|
|
36
|
+
metadata.framework = 'Svelte';
|
|
37
|
+
}
|
|
38
|
+
else if (allDeps['next']) {
|
|
39
|
+
metadata.framework = 'Next.js (React)';
|
|
40
|
+
}
|
|
41
|
+
else if (allDeps['nuxt']) {
|
|
42
|
+
metadata.framework = 'Nuxt.js (Vue)';
|
|
43
|
+
}
|
|
44
|
+
else if (allDeps['@remix-run/react']) {
|
|
45
|
+
metadata.framework = 'Remix (React)';
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Проверяем есть ли хоть что-то frontend
|
|
49
|
+
const hasFrontend = ['jquery', 'bootstrap', 'tailwindcss', '@mui/material'].some(dep => allDeps[dep]);
|
|
50
|
+
metadata.framework = hasFrontend ? 'Vanilla JS (no framework)' : 'None (backend only)';
|
|
51
|
+
}
|
|
52
|
+
// Определяем backend framework
|
|
53
|
+
if (allDeps['express']) {
|
|
54
|
+
metadata.backend = 'Express';
|
|
55
|
+
}
|
|
56
|
+
else if (allDeps['fastify']) {
|
|
57
|
+
metadata.backend = 'Fastify';
|
|
58
|
+
}
|
|
59
|
+
else if (allDeps['@nestjs/core']) {
|
|
60
|
+
metadata.backend = 'NestJS';
|
|
61
|
+
}
|
|
62
|
+
else if (allDeps['koa']) {
|
|
63
|
+
metadata.backend = 'Koa';
|
|
64
|
+
}
|
|
65
|
+
else if (allDeps['hapi']) {
|
|
66
|
+
metadata.backend = 'Hapi';
|
|
67
|
+
}
|
|
68
|
+
// Определяем database
|
|
69
|
+
if (allDeps['pg'] || allDeps['postgres']) {
|
|
70
|
+
metadata.database = 'PostgreSQL';
|
|
71
|
+
}
|
|
72
|
+
else if (allDeps['mongodb'] || allDeps['mongoose']) {
|
|
73
|
+
metadata.database = 'MongoDB';
|
|
74
|
+
}
|
|
75
|
+
else if (allDeps['mysql'] || allDeps['mysql2']) {
|
|
76
|
+
metadata.database = 'MySQL';
|
|
77
|
+
}
|
|
78
|
+
else if (allDeps['sqlite3'] || allDeps['better-sqlite3']) {
|
|
79
|
+
metadata.database = 'SQLite';
|
|
80
|
+
}
|
|
81
|
+
else if (allDeps['redis'] || allDeps['ioredis']) {
|
|
82
|
+
metadata.database = 'Redis';
|
|
83
|
+
}
|
|
84
|
+
// Определяем build tool
|
|
85
|
+
if (allDeps['vite'] || devDeps['vite']) {
|
|
86
|
+
metadata.buildTool = 'Vite';
|
|
87
|
+
}
|
|
88
|
+
else if (allDeps['webpack'] || devDeps['webpack']) {
|
|
89
|
+
metadata.buildTool = 'Webpack';
|
|
90
|
+
}
|
|
91
|
+
else if (allDeps['rollup'] || devDeps['rollup']) {
|
|
92
|
+
metadata.buildTool = 'Rollup';
|
|
93
|
+
}
|
|
94
|
+
else if (allDeps['parcel'] || devDeps['parcel']) {
|
|
95
|
+
metadata.buildTool = 'Parcel';
|
|
96
|
+
}
|
|
97
|
+
else if (allDeps['esbuild'] || devDeps['esbuild']) {
|
|
98
|
+
metadata.buildTool = 'esbuild';
|
|
99
|
+
}
|
|
100
|
+
Logger.info(`Project stack detected: ${metadata.framework || 'Unknown'} + ${metadata.backend || 'Unknown'}`);
|
|
101
|
+
return metadata;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
Logger.error('Failed to analyze project stack:', error);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Создает человекочитаемое описание стека проекта
|
|
110
|
+
*/
|
|
111
|
+
export function describeProjectStack(metadata) {
|
|
112
|
+
if (!metadata) {
|
|
113
|
+
return 'Unknown stack (package.json not found)';
|
|
114
|
+
}
|
|
115
|
+
const parts = [];
|
|
116
|
+
if (metadata.framework && metadata.framework !== 'None (backend only)') {
|
|
117
|
+
parts.push(`Frontend: ${metadata.framework}`);
|
|
118
|
+
}
|
|
119
|
+
if (metadata.backend) {
|
|
120
|
+
parts.push(`Backend: ${metadata.backend}`);
|
|
121
|
+
}
|
|
122
|
+
if (metadata.database) {
|
|
123
|
+
parts.push(`Database: ${metadata.database}`);
|
|
124
|
+
}
|
|
125
|
+
if (metadata.buildTool) {
|
|
126
|
+
parts.push(`Build: ${metadata.buildTool}`);
|
|
127
|
+
}
|
|
128
|
+
return parts.length > 0 ? parts.join(', ') : 'Minimal project (no major frameworks)';
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=project-analyzer.js.map
|