import { BaseFormatter } from '../classes.baseformatter.js'; import type { IPlannedChange } from '../interfaces.format.js'; import * as plugins from '../mod.plugins.js'; import { logger } from '../../gitzone.logging.js'; // Standard gitignore template content (without front-matter) const GITIGNORE_TEMPLATE = `.nogit/ # artifacts coverage/ public/ # installs node_modules/ # caches .yarn/ .cache/ .rpt2_cache # builds dist/ dist_*/ # AI .claude/ .serena/ #------# custom`; export class GitignoreFormatter extends BaseFormatter { get name(): string { return 'gitignore'; } async analyze(): Promise { const changes: IPlannedChange[] = []; const gitignorePath = '.gitignore'; // Check if file exists and extract custom content let customContent = ''; const exists = await plugins.smartfs.file(gitignorePath).exists(); if (exists) { const existingContent = (await plugins.smartfs .file(gitignorePath) .encoding('utf8') .read()) as string; // Extract custom section content const customMarkers = ['#------# custom', '# custom']; for (const marker of customMarkers) { const splitResult = existingContent.split(marker); if (splitResult.length > 1) { customContent = splitResult[1].trim(); break; } } } // Compute new content let newContent = GITIGNORE_TEMPLATE; if (customContent) { newContent = GITIGNORE_TEMPLATE + '\n' + customContent + '\n'; } else { newContent = GITIGNORE_TEMPLATE + '\n'; } // Read current content to compare let currentContent = ''; if (exists) { currentContent = (await plugins.smartfs .file(gitignorePath) .encoding('utf8') .read()) as string; } // Determine change type if (!exists) { changes.push({ type: 'create', path: gitignorePath, module: this.name, description: 'Create .gitignore', content: newContent, }); } else if (newContent !== currentContent) { changes.push({ type: 'modify', path: gitignorePath, module: this.name, description: 'Update .gitignore (preserving custom section)', content: newContent, }); } return changes; } async applyChange(change: IPlannedChange): Promise { if (!change.content) return; if (change.type === 'create') { await this.createFile(change.path, change.content); logger.log('info', 'Created .gitignore'); } else if (change.type === 'modify') { await this.modifyFile(change.path, change.content); logger.log('info', 'Updated .gitignore (preserved custom section)'); } } }