repomix
Version:
A tool to pack repository contents to single file for AI consumption
99 lines (98 loc) • 5.09 kB
JavaScript
import { withMemoryLogging } from '../../shared/memoryUtils.js';
import { calculateMetrics } from '../metrics/calculateMetrics.js';
import { buildOutputGeneratorContext, createRenderContext } from '../output/outputGenerate.js';
import { sortOutputFiles } from '../output/outputSort.js';
import { generateFilesSection, generateStructureSection, generateSummarySection } from './skillSectionGenerators.js';
import { calculateStatistics, generateStatisticsSection } from './skillStatistics.js';
import { generateSkillMd } from './skillStyle.js';
import { detectTechStack, generateTechStackMd } from './skillTechStack.js';
import { generateDefaultSkillName, generateProjectName, generateSkillDescription, validateSkillName, } from './skillUtils.js';
import { writeSkillOutput } from './writeSkillOutput.js';
const defaultDeps = {
buildOutputGeneratorContext,
sortOutputFiles,
calculateMetrics,
writeSkillOutput,
generateDefaultSkillName,
};
export const generateSkillReferences = async (skillName, rootDirs, config, processedFiles, allFilePaths, gitDiffResult = undefined, gitLogResult = undefined, skillProjectName, skillSourceUrl, deps = {
buildOutputGeneratorContext,
sortOutputFiles,
}) => {
const normalizedSkillName = validateSkillName(skillName);
const projectName = skillProjectName ?? generateProjectName(rootDirs);
const skillDescription = generateSkillDescription(normalizedSkillName, projectName);
const sortedProcessedFiles = await deps.sortOutputFiles(processedFiles, config);
const markdownConfig = {
...config,
output: {
...config.output,
style: 'markdown',
},
};
const outputGeneratorContext = await deps.buildOutputGeneratorContext(rootDirs, markdownConfig, allFilePaths, sortedProcessedFiles, gitDiffResult, gitLogResult);
const renderContext = createRenderContext(outputGeneratorContext);
const statistics = calculateStatistics(sortedProcessedFiles, renderContext.fileLineCounts);
const statisticsSection = generateStatisticsSection(statistics);
const techStacks = detectTechStack(sortedProcessedFiles);
const techStackMd = techStacks.length > 0 ? generateTechStackMd(techStacks) : undefined;
const references = {
summary: generateSummarySection(renderContext, statisticsSection),
structure: generateStructureSection(renderContext),
files: generateFilesSection(renderContext),
techStack: techStackMd,
};
return {
references,
skillName: normalizedSkillName,
projectName,
skillDescription,
totalFiles: sortedProcessedFiles.length,
totalLines: statistics.totalLines,
statisticsSection,
hasTechStack: techStacks.length > 0,
sourceUrl: skillSourceUrl,
};
};
export const generateSkillMdFromReferences = (referencesResult, totalTokens) => {
const skillMd = generateSkillMd({
skillName: referencesResult.skillName,
skillDescription: referencesResult.skillDescription,
projectName: referencesResult.projectName,
totalFiles: referencesResult.totalFiles,
totalLines: referencesResult.totalLines,
totalTokens,
hasTechStack: referencesResult.hasTechStack,
sourceUrl: referencesResult.sourceUrl,
});
return {
skillMd,
references: referencesResult.references,
};
};
export const packSkill = async (params, deps = defaultDeps) => {
const { rootDirs, config, options, processedFiles, allFilePaths, gitDiffResult, gitLogResult, suspiciousFilesResults, suspiciousGitDiffResults, suspiciousGitLogResults, safeFilePaths, skippedFiles, progressCallback, } = params;
const { skillDir } = options;
if (!skillDir) {
throw new Error('skillDir is required for skill generation');
}
const skillName = options.skillName ??
(typeof config.skillGenerate === 'string' ? config.skillGenerate : deps.generateDefaultSkillName(rootDirs));
const skillReferencesResult = await withMemoryLogging('Generate Skill References', () => generateSkillReferences(skillName, rootDirs, config, processedFiles, allFilePaths, gitDiffResult, gitLogResult, options.skillProjectName, options.skillSourceUrl, {
buildOutputGeneratorContext: deps.buildOutputGeneratorContext,
sortOutputFiles: deps.sortOutputFiles,
}));
const skillMetrics = await withMemoryLogging('Calculate Skill Metrics', () => deps.calculateMetrics(processedFiles, Promise.resolve(skillReferencesResult.references.files), progressCallback, config, gitDiffResult, gitLogResult));
const skillOutput = generateSkillMdFromReferences(skillReferencesResult, skillMetrics.totalTokens);
progressCallback('Writing skill output...');
await withMemoryLogging('Write Skill Output', () => deps.writeSkillOutput(skillOutput, skillDir));
return {
...skillMetrics,
suspiciousFilesResults,
suspiciousGitDiffResults,
suspiciousGitLogResults,
processedFiles,
safeFilePaths,
skippedFiles,
};
};