diff --git a/src/index.ts b/src/index.ts index 7fe67c2..00745d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -489,24 +489,30 @@ function readAgentsFile(filePath: string): string | null { */ function parseAgentsContent( content: string, -): Record { - const sections: Record = {}; +): Record { + const sections: Record< + string, + { title: string; content: string; level: number } + > = {}; const lines = content.split('\n'); let currentKey = ''; let currentTitle = ''; + let currentLevel = 0; let currentContent: string[] = []; for (const line of lines) { - const sectionMatch = line.match(/^##\s+(.+)$/); + const sectionMatch = line.match(/^(#{1,2})\s+(.+)$/); if (sectionMatch) { if (currentKey) { sections[currentKey] = { title: currentTitle, + level: currentLevel, content: currentContent.join('\n').trim(), }; } - currentTitle = sectionMatch[1]; - currentKey = sectionMatch[1].toLowerCase(); + currentLevel = sectionMatch[1].length; + currentTitle = sectionMatch[2].trim(); + currentKey = `${currentLevel}-${currentTitle.toLowerCase()}`; currentContent = []; } else if (currentKey) { currentContent.push(line); @@ -516,6 +522,7 @@ function parseAgentsContent( if (currentKey) { sections[currentKey] = { title: currentTitle, + level: currentLevel, content: currentContent.join('\n').trim(), }; } @@ -527,7 +534,10 @@ function parseAgentsContent( * Merge AGENTS.md files from multiple sources */ function mergeAgentsFiles(agentsFiles: string[]): string { - const allSections: Record = {}; + const allSections: Record< + string, + { title: string; level: number; contents: string[] } + > = {}; for (const fileContent of agentsFiles) { if (!fileContent) continue; @@ -535,7 +545,11 @@ function mergeAgentsFiles(agentsFiles: string[]): string { for (const [key, section] of Object.entries(sections)) { if (!allSections[key]) { - allSections[key] = { title: section.title, contents: [] }; + allSections[key] = { + title: section.title, + level: section.level, + contents: [], + }; } if ( section.content && @@ -549,7 +563,7 @@ function mergeAgentsFiles(agentsFiles: string[]): string { const result: string[] = []; for (const [, section] of Object.entries(allSections)) { - result.push(`## ${section.title}`); + result.push(`${'#'.repeat(section.level)} ${section.title}`); result.push(''); for (const content of section.contents) { result.push(content); diff --git a/test/agents.test.ts b/test/agents.test.ts index c2d9367..b7e0f24 100644 --- a/test/agents.test.ts +++ b/test/agents.test.ts @@ -116,3 +116,27 @@ test('should generate AGENTS.md with eslint tool and template mapping', async () assert.match(content, /## Tools/); assert.match(content, /### ESLint/); // from template-eslint/AGENTS.md }); + +test('should merge top-level sections from AGENTS.md files', async () => { + const projectDir = path.join(testDir, 'h1-support'); + process.argv = ['node', 'test', '--dir', projectDir, '--template', 'vanilla']; + + await create({ + name: 'test', + root: fixturesDir, + templates: ['vanilla'], + getTemplateName: async () => 'vanilla', + mapESLintTemplate: () => null, + }); + + const agentsPath = path.join(projectDir, 'AGENTS.md'); + assert.strictEqual(fs.existsSync(agentsPath), true); + + const content = fs.readFileSync(agentsPath, 'utf-8'); + const h1Matches = content.match(/^# Project Overview$/gm) ?? []; + assert.strictEqual(h1Matches.length, 1); + assert.match( + content, + /This section provides common guidance for all templates./, + ); +}); diff --git a/test/fixtures/agents-md/template-common/AGENTS.md b/test/fixtures/agents-md/template-common/AGENTS.md index 0507fb9..0c730d1 100644 --- a/test/fixtures/agents-md/template-common/AGENTS.md +++ b/test/fixtures/agents-md/template-common/AGENTS.md @@ -1,3 +1,7 @@ +# Project Overview + +This section provides common guidance for all templates. + ## Development ### Common Development @@ -7,4 +11,4 @@ ## Tools ### Common Tools -- Tools that apply to all templates \ No newline at end of file +- Tools that apply to all templates