UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

264 lines (252 loc) 8.43 kB
import fs from 'fs-extra'; import * as path from 'path'; import { DocumentationHealer } from './DocumentationHealer.js'; import { GitHooksHealer } from './GitHooksHealer.js'; import { ProjectStructureHealer } from './ProjectStructureHealer.js'; export class ProjectHealer { projectRoot; documentationHealer; gitHooksHealer; projectStructureHealer; constructor(projectRoot) { this.projectRoot = projectRoot; this.documentationHealer = new DocumentationHealer(projectRoot); this.gitHooksHealer = new GitHooksHealer(projectRoot); this.projectStructureHealer = new ProjectStructureHealer(projectRoot); } async identifyHealableIssues(analysisResult) { const issues = []; // Check project structure issues const structureIssues = await this.projectStructureHealer.checkStructure(); if (structureIssues.length > 0) { issues.push({ id: 'project-structure', description: `Project structure issues: ${structureIssues.join(', ')}`, severity: 'high', category: 'project-setup', autoFixable: true, fix: async () => this.projectStructureHealer.heal() }); } // Check for missing README if (!await fs.pathExists(path.join(this.projectRoot, 'README.md'))) { issues.push({ id: 'missing-readme', description: 'Missing README.md file', severity: 'medium', category: 'documentation', autoFixable: true, fix: async () => this.documentationHealer.heal(analysisResult.projectInfo || this.getDefaultProjectInfo()) }); } // Check for missing .gitignore if (!await fs.pathExists(path.join(this.projectRoot, '.gitignore'))) { issues.push({ id: 'missing-gitignore', description: 'Missing .gitignore file', severity: 'high', category: 'project-setup', autoFixable: true, fix: async () => this.createGitignore() }); } // Check for missing EditorConfig if (!await fs.pathExists(path.join(this.projectRoot, '.editorconfig'))) { issues.push({ id: 'missing-editorconfig', description: 'Missing .editorconfig file', severity: 'low', category: 'code-style', autoFixable: true, fix: async () => this.createEditorConfig() }); } // Check for missing linter config const hasLinter = await this.checkForLinter(); if (!hasLinter && await fs.pathExists(path.join(this.projectRoot, 'package.json'))) { issues.push({ id: 'missing-linter', description: 'Missing ESLint configuration', severity: 'medium', category: 'code-quality', autoFixable: true, fix: async () => this.createEslintConfig() }); } // Check for missing Prettier config const hasFormatter = await this.checkForFormatter(); if (!hasFormatter && await fs.pathExists(path.join(this.projectRoot, 'package.json'))) { issues.push({ id: 'missing-formatter', description: 'Missing Prettier configuration', severity: 'low', category: 'code-style', autoFixable: true, fix: async () => this.createPrettierConfig() }); } // Check for git hooks if (await fs.pathExists(path.join(this.projectRoot, '.git'))) { const hasPreCommit = await fs.pathExists(path.join(this.projectRoot, '.git', 'hooks', 'pre-commit')); const hasPostCommit = await fs.pathExists(path.join(this.projectRoot, '.git', 'hooks', 'post-commit')); if (!hasPreCommit || !hasPostCommit) { issues.push({ id: 'missing-git-hooks', description: 'Missing MIRA git hooks for enhanced development workflow', severity: 'medium', category: 'development-workflow', autoFixable: true, fix: async () => this.gitHooksHealer.heal() }); } } return issues; } getDefaultProjectInfo() { return { name: path.basename(this.projectRoot), type: 'unknown', languages: [], frameworks: [], hasTests: false, hasCI: false }; } async healAll(issues) { const result = { success: 0, failed: 0, details: [] }; for (const issue of issues) { if (issue.autoFixable && issue.fix) { try { await issue.fix(); result.success++; result.details.push({ issue: issue.description, status: 'success' }); } catch (error) { result.failed++; result.details.push({ issue: issue.description, status: 'failed', error: error instanceof Error ? error.message : 'Unknown error' }); } } else { result.failed++; result.details.push({ issue: issue.description, status: 'failed', error: 'Not auto-fixable' }); } } return result; } async createGitignore() { const gitignore = `# Dependencies node_modules/ # Build outputs dist/ build/ *.tsbuildinfo # Logs logs/ *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Environment files .env .env.local .env.*.local # IDE files .vscode/ .idea/ *.swp *.swo .DS_Store # Test coverage coverage/ .nyc_output/ # Temporary files tmp/ temp/ *.tmp # MIRA .mira/reports/ `; await fs.writeFile(path.join(this.projectRoot, '.gitignore'), gitignore); } async createEditorConfig() { const editorConfig = `# EditorConfig is awesome: https://EditorConfig.org root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false [*.{js,jsx,ts,tsx,json}] indent_size = 2 [*.py] indent_size = 4 `; await fs.writeFile(path.join(this.projectRoot, '.editorconfig'), editorConfig); } async createEslintConfig() { const eslintConfig = { env: { browser: true, es2021: true, node: true }, extends: [ 'eslint:recommended' ], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, rules: { 'no-console': 'warn', 'no-unused-vars': 'warn' } }; await fs.writeJson(path.join(this.projectRoot, '.eslintrc.json'), eslintConfig, { spaces: 2 }); } async createPrettierConfig() { const prettierConfig = { semi: true, trailingComma: 'es5', singleQuote: true, printWidth: 100, tabWidth: 2 }; await fs.writeJson(path.join(this.projectRoot, '.prettierrc'), prettierConfig, { spaces: 2 }); } async checkForLinter() { const linterFiles = ['.eslintrc', '.eslintrc.js', '.eslintrc.json', '.eslintrc.yml']; for (const file of linterFiles) { if (await fs.pathExists(path.join(this.projectRoot, file))) { return true; } } return false; } async checkForFormatter() { const formatterFiles = ['.prettierrc', '.prettierrc.js', '.prettierrc.json', '.prettierrc.yml']; for (const file of formatterFiles) { if (await fs.pathExists(path.join(this.projectRoot, file))) { return true; } } return false; } } //# sourceMappingURL=ProjectHealer.js.map