aios-core 2.1.3 → 2.1.5
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/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +6 -6
- package/.claude/rules/mcp-usage.md +55 -9
- package/package.json +1 -1
- package/packages/installer/src/config/templates/env-template.js +2 -2
- package/packages/installer/src/wizard/wizard.js +34 -185
- package/src/wizard/index.js +2 -2
- package/.aios-core/development/tasks/analyze-brownfield.md +0 -456
- package/.aios-core/development/tasks/setup-project-docs.md +0 -444
- package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +0 -501
- package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +0 -329
- package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +0 -282
- package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +0 -331
- package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +0 -312
- package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +0 -74
- package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +0 -358
- package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +0 -182
- package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +0 -127
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +0 -63
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +0 -18
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +0 -85
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +0 -145
- package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +0 -346
- package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +0 -177
- package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +0 -267
|
@@ -1,501 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Brownfield Analyzer Module
|
|
3
|
-
*
|
|
4
|
-
* Analyzes existing projects to detect structure, standards, and tech stack.
|
|
5
|
-
* Used for brownfield mode installation to adapt AIOS to existing projects.
|
|
6
|
-
*
|
|
7
|
-
* @module documentation-integrity/brownfield-analyzer
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
* @story 6.9
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Analysis result structure
|
|
17
|
-
* @typedef {Object} BrownfieldAnalysis
|
|
18
|
-
* @property {boolean} hasExistingStructure - Has defined directory structure
|
|
19
|
-
* @property {boolean} hasExistingWorkflows - Has CI/CD workflows
|
|
20
|
-
* @property {boolean} hasExistingStandards - Has coding standard configs
|
|
21
|
-
* @property {string} mergeStrategy - Recommended merge strategy
|
|
22
|
-
* @property {string[]} techStack - Detected technologies
|
|
23
|
-
* @property {string[]} frameworks - Detected frameworks
|
|
24
|
-
* @property {Object} configs - Detected config file paths
|
|
25
|
-
* @property {string[]} recommendations - Recommendations for integration
|
|
26
|
-
* @property {string[]} conflicts - Potential conflicts detected
|
|
27
|
-
* @property {string[]} manualReviewItems - Items needing manual review
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Analyzes an existing project for brownfield integration
|
|
32
|
-
*
|
|
33
|
-
* @param {string} targetDir - Directory to analyze
|
|
34
|
-
* @returns {BrownfieldAnalysis} Analysis results
|
|
35
|
-
*/
|
|
36
|
-
function analyzeProject(targetDir) {
|
|
37
|
-
const normalizedDir = path.resolve(targetDir);
|
|
38
|
-
|
|
39
|
-
if (!fs.existsSync(normalizedDir)) {
|
|
40
|
-
throw new Error(`Directory does not exist: ${normalizedDir}`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const analysis = {
|
|
44
|
-
// Basic flags
|
|
45
|
-
hasExistingStructure: false,
|
|
46
|
-
hasExistingWorkflows: false,
|
|
47
|
-
hasExistingStandards: false,
|
|
48
|
-
|
|
49
|
-
// Merge strategy
|
|
50
|
-
mergeStrategy: 'parallel',
|
|
51
|
-
|
|
52
|
-
// Detected stack
|
|
53
|
-
techStack: [],
|
|
54
|
-
frameworks: [],
|
|
55
|
-
version: null,
|
|
56
|
-
|
|
57
|
-
// Config paths
|
|
58
|
-
configs: {
|
|
59
|
-
eslint: null,
|
|
60
|
-
prettier: null,
|
|
61
|
-
tsconfig: null,
|
|
62
|
-
flake8: null,
|
|
63
|
-
packageJson: null,
|
|
64
|
-
requirements: null,
|
|
65
|
-
goMod: null,
|
|
66
|
-
githubWorkflows: null,
|
|
67
|
-
gitlabCi: null,
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
// Detected settings
|
|
71
|
-
linting: 'none',
|
|
72
|
-
formatting: 'none',
|
|
73
|
-
testing: 'none',
|
|
74
|
-
|
|
75
|
-
// Integration guidance
|
|
76
|
-
recommendations: [],
|
|
77
|
-
conflicts: [],
|
|
78
|
-
manualReviewItems: [],
|
|
79
|
-
|
|
80
|
-
// Summary
|
|
81
|
-
summary: '',
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Run all analyzers
|
|
85
|
-
analyzeTechStack(normalizedDir, analysis);
|
|
86
|
-
analyzeCodeStandards(normalizedDir, analysis);
|
|
87
|
-
analyzeWorkflows(normalizedDir, analysis);
|
|
88
|
-
analyzeDirectoryStructure(normalizedDir, analysis);
|
|
89
|
-
generateRecommendations(analysis);
|
|
90
|
-
generateSummary(analysis);
|
|
91
|
-
|
|
92
|
-
return analysis;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Analyzes the tech stack from project files
|
|
97
|
-
*
|
|
98
|
-
* @param {string} targetDir - Directory to analyze
|
|
99
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to populate
|
|
100
|
-
*/
|
|
101
|
-
function analyzeTechStack(targetDir, analysis) {
|
|
102
|
-
// Check for Node.js
|
|
103
|
-
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
104
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
105
|
-
analysis.techStack.push('Node.js');
|
|
106
|
-
analysis.configs.packageJson = 'package.json';
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
110
|
-
analysis.version = pkg.version;
|
|
111
|
-
|
|
112
|
-
// Detect frameworks from dependencies
|
|
113
|
-
const allDeps = {
|
|
114
|
-
...(pkg.dependencies || {}),
|
|
115
|
-
...(pkg.devDependencies || {}),
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
if (allDeps.react) analysis.frameworks.push('React');
|
|
119
|
-
if (allDeps.vue) analysis.frameworks.push('Vue');
|
|
120
|
-
if (allDeps.angular || allDeps['@angular/core']) analysis.frameworks.push('Angular');
|
|
121
|
-
if (allDeps.next) analysis.frameworks.push('Next.js');
|
|
122
|
-
if (allDeps.nuxt) analysis.frameworks.push('Nuxt');
|
|
123
|
-
if (allDeps.express) analysis.frameworks.push('Express');
|
|
124
|
-
if (allDeps.fastify) analysis.frameworks.push('Fastify');
|
|
125
|
-
if (allDeps.nest || allDeps['@nestjs/core']) analysis.frameworks.push('NestJS');
|
|
126
|
-
|
|
127
|
-
// Detect TypeScript
|
|
128
|
-
if (allDeps.typescript || fs.existsSync(path.join(targetDir, 'tsconfig.json'))) {
|
|
129
|
-
analysis.techStack.push('TypeScript');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Detect testing frameworks
|
|
133
|
-
if (allDeps.jest) analysis.testing = 'Jest';
|
|
134
|
-
else if (allDeps.mocha) analysis.testing = 'Mocha';
|
|
135
|
-
else if (allDeps.vitest) analysis.testing = 'Vitest';
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.warn(`Warning: Could not parse package.json: ${error.message}`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Check for Python
|
|
142
|
-
if (
|
|
143
|
-
fs.existsSync(path.join(targetDir, 'requirements.txt')) ||
|
|
144
|
-
fs.existsSync(path.join(targetDir, 'pyproject.toml')) ||
|
|
145
|
-
fs.existsSync(path.join(targetDir, 'setup.py'))
|
|
146
|
-
) {
|
|
147
|
-
analysis.techStack.push('Python');
|
|
148
|
-
|
|
149
|
-
if (fs.existsSync(path.join(targetDir, 'requirements.txt'))) {
|
|
150
|
-
analysis.configs.requirements = 'requirements.txt';
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const requirements = fs.readFileSync(
|
|
154
|
-
path.join(targetDir, 'requirements.txt'),
|
|
155
|
-
'utf8',
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
if (requirements.includes('django')) analysis.frameworks.push('Django');
|
|
159
|
-
if (requirements.includes('flask')) analysis.frameworks.push('Flask');
|
|
160
|
-
if (requirements.includes('fastapi')) analysis.frameworks.push('FastAPI');
|
|
161
|
-
if (requirements.includes('pytest')) analysis.testing = 'pytest';
|
|
162
|
-
} catch {
|
|
163
|
-
// Ignore parse errors
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Check for Go
|
|
169
|
-
if (fs.existsSync(path.join(targetDir, 'go.mod'))) {
|
|
170
|
-
analysis.techStack.push('Go');
|
|
171
|
-
analysis.configs.goMod = 'go.mod';
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Check for Rust
|
|
175
|
-
if (fs.existsSync(path.join(targetDir, 'Cargo.toml'))) {
|
|
176
|
-
analysis.techStack.push('Rust');
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Analyzes existing coding standards configurations
|
|
182
|
-
*
|
|
183
|
-
* @param {string} targetDir - Directory to analyze
|
|
184
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to populate
|
|
185
|
-
*/
|
|
186
|
-
function analyzeCodeStandards(targetDir, analysis) {
|
|
187
|
-
// ESLint
|
|
188
|
-
const eslintConfigs = [
|
|
189
|
-
'.eslintrc.js',
|
|
190
|
-
'.eslintrc.json',
|
|
191
|
-
'.eslintrc.yaml',
|
|
192
|
-
'.eslintrc.yml',
|
|
193
|
-
'.eslintrc',
|
|
194
|
-
'eslint.config.js',
|
|
195
|
-
];
|
|
196
|
-
|
|
197
|
-
for (const config of eslintConfigs) {
|
|
198
|
-
if (fs.existsSync(path.join(targetDir, config))) {
|
|
199
|
-
analysis.configs.eslint = config;
|
|
200
|
-
analysis.linting = 'ESLint';
|
|
201
|
-
analysis.hasExistingStandards = true;
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Prettier
|
|
207
|
-
const prettierConfigs = [
|
|
208
|
-
'.prettierrc',
|
|
209
|
-
'.prettierrc.json',
|
|
210
|
-
'.prettierrc.yaml',
|
|
211
|
-
'.prettierrc.yml',
|
|
212
|
-
'.prettierrc.js',
|
|
213
|
-
'prettier.config.js',
|
|
214
|
-
];
|
|
215
|
-
|
|
216
|
-
for (const config of prettierConfigs) {
|
|
217
|
-
if (fs.existsSync(path.join(targetDir, config))) {
|
|
218
|
-
analysis.configs.prettier = config;
|
|
219
|
-
analysis.formatting = 'Prettier';
|
|
220
|
-
analysis.hasExistingStandards = true;
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// TypeScript
|
|
226
|
-
if (fs.existsSync(path.join(targetDir, 'tsconfig.json'))) {
|
|
227
|
-
analysis.configs.tsconfig = 'tsconfig.json';
|
|
228
|
-
analysis.hasExistingStandards = true;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Python - Flake8
|
|
232
|
-
if (fs.existsSync(path.join(targetDir, '.flake8'))) {
|
|
233
|
-
analysis.configs.flake8 = '.flake8';
|
|
234
|
-
analysis.linting = 'Flake8';
|
|
235
|
-
analysis.hasExistingStandards = true;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Python - Black
|
|
239
|
-
const pyprojectPath = path.join(targetDir, 'pyproject.toml');
|
|
240
|
-
if (fs.existsSync(pyprojectPath)) {
|
|
241
|
-
try {
|
|
242
|
-
const content = fs.readFileSync(pyprojectPath, 'utf8');
|
|
243
|
-
if (content.includes('[tool.black]')) {
|
|
244
|
-
analysis.formatting = 'Black';
|
|
245
|
-
analysis.hasExistingStandards = true;
|
|
246
|
-
}
|
|
247
|
-
} catch {
|
|
248
|
-
// Ignore
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Analyzes existing CI/CD workflows
|
|
255
|
-
*
|
|
256
|
-
* @param {string} targetDir - Directory to analyze
|
|
257
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to populate
|
|
258
|
-
*/
|
|
259
|
-
function analyzeWorkflows(targetDir, analysis) {
|
|
260
|
-
// GitHub Actions
|
|
261
|
-
const githubWorkflowsDir = path.join(targetDir, '.github', 'workflows');
|
|
262
|
-
if (fs.existsSync(githubWorkflowsDir)) {
|
|
263
|
-
analysis.hasExistingWorkflows = true;
|
|
264
|
-
analysis.configs.githubWorkflows = '.github/workflows/';
|
|
265
|
-
|
|
266
|
-
try {
|
|
267
|
-
const workflows = fs.readdirSync(githubWorkflowsDir);
|
|
268
|
-
if (workflows.length > 0) {
|
|
269
|
-
analysis.manualReviewItems.push(
|
|
270
|
-
`Review ${workflows.length} existing GitHub workflow(s) for potential conflicts`,
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
} catch {
|
|
274
|
-
// Ignore
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// GitLab CI
|
|
279
|
-
if (fs.existsSync(path.join(targetDir, '.gitlab-ci.yml'))) {
|
|
280
|
-
analysis.hasExistingWorkflows = true;
|
|
281
|
-
analysis.configs.gitlabCi = '.gitlab-ci.yml';
|
|
282
|
-
analysis.manualReviewItems.push('Review existing GitLab CI configuration');
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// CircleCI
|
|
286
|
-
if (fs.existsSync(path.join(targetDir, '.circleci', 'config.yml'))) {
|
|
287
|
-
analysis.hasExistingWorkflows = true;
|
|
288
|
-
analysis.manualReviewItems.push('Review existing CircleCI configuration');
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Analyzes the directory structure
|
|
294
|
-
*
|
|
295
|
-
* @param {string} targetDir - Directory to analyze
|
|
296
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to populate
|
|
297
|
-
*/
|
|
298
|
-
function analyzeDirectoryStructure(targetDir, analysis) {
|
|
299
|
-
// Common source directories
|
|
300
|
-
const srcDirs = ['src', 'lib', 'app', 'source', 'pkg', 'cmd', 'internal'];
|
|
301
|
-
const testDirs = ['test', 'tests', '__tests__', 'spec'];
|
|
302
|
-
const docDirs = ['docs', 'doc', 'documentation'];
|
|
303
|
-
|
|
304
|
-
let hasSrcDir = false;
|
|
305
|
-
let hasTestDir = false;
|
|
306
|
-
let hasDocDir = false;
|
|
307
|
-
|
|
308
|
-
try {
|
|
309
|
-
const contents = fs.readdirSync(targetDir);
|
|
310
|
-
|
|
311
|
-
for (const item of contents) {
|
|
312
|
-
const itemPath = path.join(targetDir, item);
|
|
313
|
-
if (fs.statSync(itemPath).isDirectory()) {
|
|
314
|
-
if (srcDirs.includes(item.toLowerCase())) hasSrcDir = true;
|
|
315
|
-
if (testDirs.includes(item.toLowerCase())) hasTestDir = true;
|
|
316
|
-
if (docDirs.includes(item.toLowerCase())) hasDocDir = true;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
} catch {
|
|
320
|
-
// Ignore
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
analysis.hasExistingStructure = hasSrcDir || hasTestDir;
|
|
324
|
-
|
|
325
|
-
// Check for docs/architecture conflict
|
|
326
|
-
if (hasDocDir) {
|
|
327
|
-
const archDir = path.join(targetDir, 'docs', 'architecture');
|
|
328
|
-
if (fs.existsSync(archDir)) {
|
|
329
|
-
analysis.conflicts.push(
|
|
330
|
-
'docs/architecture/ already exists - AIOS docs may need different location',
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Generates recommendations based on analysis
|
|
338
|
-
*
|
|
339
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to update
|
|
340
|
-
*/
|
|
341
|
-
function generateRecommendations(analysis) {
|
|
342
|
-
// Linting recommendations
|
|
343
|
-
if (analysis.linting !== 'none') {
|
|
344
|
-
analysis.recommendations.push(
|
|
345
|
-
`Preserve existing ${analysis.linting} configuration - AIOS will adapt`,
|
|
346
|
-
);
|
|
347
|
-
} else {
|
|
348
|
-
analysis.recommendations.push('Consider adding ESLint/Flake8 for code quality');
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Formatting recommendations
|
|
352
|
-
if (analysis.formatting !== 'none') {
|
|
353
|
-
analysis.recommendations.push(
|
|
354
|
-
`Keep existing ${analysis.formatting} settings - AIOS coding-standards.md will document them`,
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Workflow recommendations
|
|
359
|
-
if (analysis.hasExistingWorkflows) {
|
|
360
|
-
analysis.recommendations.push('Review existing CI/CD before adding AIOS workflows');
|
|
361
|
-
analysis.mergeStrategy = 'manual';
|
|
362
|
-
} else {
|
|
363
|
-
analysis.recommendations.push('Use *setup-github to add AIOS standard workflows');
|
|
364
|
-
analysis.mergeStrategy = 'parallel';
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// TypeScript recommendations
|
|
368
|
-
if (analysis.configs.tsconfig) {
|
|
369
|
-
analysis.recommendations.push('AIOS will use existing tsconfig.json settings');
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Framework-specific
|
|
373
|
-
if (analysis.frameworks.includes('Next.js')) {
|
|
374
|
-
analysis.recommendations.push('Next.js detected - use pages/ or app/ structure');
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (analysis.frameworks.includes('NestJS')) {
|
|
378
|
-
analysis.recommendations.push('NestJS detected - AIOS will adapt to module structure');
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Generates a summary of the analysis
|
|
384
|
-
*
|
|
385
|
-
* @param {BrownfieldAnalysis} analysis - Analysis object to update
|
|
386
|
-
*/
|
|
387
|
-
function generateSummary(analysis) {
|
|
388
|
-
const parts = [];
|
|
389
|
-
|
|
390
|
-
parts.push(`Tech Stack: ${analysis.techStack.join(', ') || 'Unknown'}`);
|
|
391
|
-
|
|
392
|
-
if (analysis.frameworks.length > 0) {
|
|
393
|
-
parts.push(`Frameworks: ${analysis.frameworks.join(', ')}`);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
if (analysis.hasExistingStandards) {
|
|
397
|
-
parts.push(`Standards: ${analysis.linting}/${analysis.formatting}`);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (analysis.hasExistingWorkflows) {
|
|
401
|
-
parts.push('CI/CD: Existing workflows detected');
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
parts.push(`Recommended Strategy: ${analysis.mergeStrategy}`);
|
|
405
|
-
|
|
406
|
-
analysis.summary = parts.join(' | ');
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Gets a migration report for display
|
|
411
|
-
*
|
|
412
|
-
* @param {BrownfieldAnalysis} analysis - Analysis results
|
|
413
|
-
* @returns {string} Formatted migration report
|
|
414
|
-
*/
|
|
415
|
-
function formatMigrationReport(analysis) {
|
|
416
|
-
const lines = [];
|
|
417
|
-
const width = 70;
|
|
418
|
-
const border = '═'.repeat(width);
|
|
419
|
-
|
|
420
|
-
lines.push(`╔${border}╗`);
|
|
421
|
-
lines.push(`║${'BROWNFIELD ANALYSIS REPORT'.padStart((width + 26) / 2).padEnd(width)}║`);
|
|
422
|
-
lines.push(`╠${border}╣`);
|
|
423
|
-
|
|
424
|
-
// Tech Stack
|
|
425
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
426
|
-
lines.push(`║ Tech Stack: ${(analysis.techStack.join(', ') || 'Unknown').padEnd(width - 16)}║`);
|
|
427
|
-
|
|
428
|
-
if (analysis.frameworks.length > 0) {
|
|
429
|
-
lines.push(`║ Frameworks: ${analysis.frameworks.join(', ').padEnd(width - 16)}║`);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Standards
|
|
433
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
434
|
-
lines.push(`║ Linting: ${analysis.linting.padEnd(width - 13)}║`);
|
|
435
|
-
lines.push(`║ Formatting: ${analysis.formatting.padEnd(width - 16)}║`);
|
|
436
|
-
lines.push(`║ Testing: ${analysis.testing.padEnd(width - 13)}║`);
|
|
437
|
-
|
|
438
|
-
// Workflows
|
|
439
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
440
|
-
lines.push(
|
|
441
|
-
`║ Existing Workflows: ${(analysis.hasExistingWorkflows ? 'Yes' : 'No').padEnd(width - 24)}║`,
|
|
442
|
-
);
|
|
443
|
-
lines.push(`║ Merge Strategy: ${analysis.mergeStrategy.padEnd(width - 20)}║`);
|
|
444
|
-
|
|
445
|
-
// Recommendations
|
|
446
|
-
if (analysis.recommendations.length > 0) {
|
|
447
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
448
|
-
lines.push(`╠${border}╣`);
|
|
449
|
-
lines.push(`║ RECOMMENDATIONS${' '.repeat(width - 18)}║`);
|
|
450
|
-
lines.push(`╠${border}╣`);
|
|
451
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
452
|
-
|
|
453
|
-
for (const rec of analysis.recommendations) {
|
|
454
|
-
const truncated = rec.substring(0, width - 6);
|
|
455
|
-
lines.push(`║ • ${truncated.padEnd(width - 5)}║`);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Conflicts
|
|
460
|
-
if (analysis.conflicts.length > 0) {
|
|
461
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
462
|
-
lines.push(`╠${border}╣`);
|
|
463
|
-
lines.push(`║ ⚠️ POTENTIAL CONFLICTS${' '.repeat(width - 25)}║`);
|
|
464
|
-
lines.push(`╠${border}╣`);
|
|
465
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
466
|
-
|
|
467
|
-
for (const conflict of analysis.conflicts) {
|
|
468
|
-
const truncated = conflict.substring(0, width - 6);
|
|
469
|
-
lines.push(`║ • ${truncated.padEnd(width - 5)}║`);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// Manual Review Items
|
|
474
|
-
if (analysis.manualReviewItems.length > 0) {
|
|
475
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
476
|
-
lines.push(`╠${border}╣`);
|
|
477
|
-
lines.push(`║ 📋 MANUAL REVIEW REQUIRED${' '.repeat(width - 28)}║`);
|
|
478
|
-
lines.push(`╠${border}╣`);
|
|
479
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
480
|
-
|
|
481
|
-
for (const item of analysis.manualReviewItems) {
|
|
482
|
-
const truncated = item.substring(0, width - 6);
|
|
483
|
-
lines.push(`║ • ${truncated.padEnd(width - 5)}║`);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
lines.push(`║${''.padEnd(width)}║`);
|
|
488
|
-
lines.push(`╚${border}╝`);
|
|
489
|
-
|
|
490
|
-
return lines.join('\n');
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
module.exports = {
|
|
494
|
-
analyzeProject,
|
|
495
|
-
analyzeTechStack,
|
|
496
|
-
analyzeCodeStandards,
|
|
497
|
-
analyzeWorkflows,
|
|
498
|
-
analyzeDirectoryStructure,
|
|
499
|
-
generateRecommendations,
|
|
500
|
-
formatMigrationReport,
|
|
501
|
-
};
|