Compare commits

...

2 Commits

Author SHA1 Message Date
Alex Verkhovsky 0071f1cf4f fix(installer): clean up temp dir leak and conditional IDE footer
- Return fixture root from createSkillCollisionFixture so cleanup
  removes the parent temp directory, not just the _bmad child
- Only show bmad-help next-step line when IDEs are configured
2026-03-12 08:11:02 -06:00
Alex Verkhovsky 55a0d963a4 style: fix prettier formatting in test file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 07:42:11 -06:00
4 changed files with 21 additions and 26 deletions

View File

@ -132,7 +132,7 @@ async function createSkillCollisionFixture() {
),
);
return fixtureDir;
return { root: fixtureRoot, bmadDir: fixtureDir };
}
/**
@ -1829,23 +1829,24 @@ async function runTests() {
// ============================================================
console.log(`${colors.yellow}Test Suite 31: Skill Count Reporting${colors.reset}\n`);
let collisionFixture = null;
let collisionFixtureRoot = null;
let collisionProjectDir = null;
try {
clearCache();
collisionFixture = await createSkillCollisionFixture();
const collisionFixture = await createSkillCollisionFixture();
collisionFixtureRoot = collisionFixture.root;
collisionProjectDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-antigravity-test-'));
const ideManager = new IdeManager();
await ideManager.ensureInitialized();
const result = await ideManager.setup('antigravity', collisionProjectDir, collisionFixture, {
const result = await ideManager.setup('antigravity', collisionProjectDir, collisionFixture.bmadDir, {
silent: true,
selectedModules: ['core'],
});
assert(result.success === true, 'Antigravity setup succeeds with overlapping skill names');
assert(result.detail === '2 skills', 'Installer detail reports unique installed skill directories');
assert(result.detail === '2 skills, 2 agents', 'Installer detail reports total skills and total agents');
assert(result.handlerResult.results.skillDirectories === 2, 'Result exposes unique skill directory count');
assert(result.handlerResult.results.agents === 2, 'Result retains generated agent write count');
assert(result.handlerResult.results.workflows === 1, 'Result retains generated workflow count');
@ -1854,12 +1855,15 @@ async function runTests() {
await fs.pathExists(path.join(collisionProjectDir, '.agent', 'skills', 'bmad-agent-bmad-master', 'SKILL.md')),
'Agent skill directory is created',
);
assert(await fs.pathExists(path.join(collisionProjectDir, '.agent', 'skills', 'bmad-help', 'SKILL.md')), 'Overlapping skill directory is created once');
assert(
await fs.pathExists(path.join(collisionProjectDir, '.agent', 'skills', 'bmad-help', 'SKILL.md')),
'Overlapping skill directory is created once',
);
} catch (error) {
assert(false, 'Skill-format unique count test succeeds', error.message);
} finally {
if (collisionProjectDir) await fs.remove(collisionProjectDir).catch(() => {});
if (collisionFixture) await fs.remove(collisionFixture).catch(() => {});
if (collisionFixtureRoot) await fs.remove(collisionFixtureRoot).catch(() => {});
}
console.log('');

View File

@ -1430,8 +1430,10 @@ class Installer {
` Join our Discord: ${color.dim('https://discord.gg/gk8jAdXWmj')}`,
` Star us on GitHub: ${color.dim('https://github.com/bmad-code-org/BMAD-METHOD/')}`,
` Subscribe on YouTube: ${color.dim('https://www.youtube.com/@BMadCode')}`,
` Invoke the ${color.cyan('bmad-help')} skill in your IDE Agent to get started`,
);
if (context.ides && context.ides.length > 0) {
lines.push(` Invoke the ${color.cyan('bmad-help')} skill in your IDE Agent to get started`);
}
await prompts.note(lines.join('\n'), 'BMAD is ready to use!');
}

View File

@ -712,15 +712,10 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
async printSummary(results, targetDir, options = {}) {
if (options.silent) return;
const parts = [];
if (results.skillDirectories > 0) {
parts.push(`${results.skillDirectories} skills`);
} else {
if (results.agents > 0) parts.push(`${results.agents} agents`);
if (results.workflows > 0) parts.push(`${results.workflows} workflows`);
if (results.tasks > 0) parts.push(`${results.tasks} tasks`);
if (results.tools > 0) parts.push(`${results.tools} tools`);
if (results.skills > 0) parts.push(`${results.skills} skills`);
}
const totalSkills =
results.skillDirectories || (results.workflows || 0) + (results.tasks || 0) + (results.tools || 0) + (results.skills || 0);
if (totalSkills > 0) parts.push(`${totalSkills} skills`);
if (results.agents > 0) parts.push(`${results.agents} agents`);
await prompts.log.success(`${this.name} configured: ${parts.join(', ')}${targetDir}`);
}

View File

@ -162,15 +162,9 @@ class IdeManager {
// Config-driven handlers return { success, results: { agents, workflows, tasks, tools } }
const r = handlerResult.results;
const parts = [];
if (r.skillDirectories > 0) {
parts.push(`${r.skillDirectories} skills`);
} else {
if (r.agents > 0) parts.push(`${r.agents} agents`);
if (r.workflows > 0) parts.push(`${r.workflows} workflows`);
if (r.tasks > 0) parts.push(`${r.tasks} tasks`);
if (r.tools > 0) parts.push(`${r.tools} tools`);
if (r.skills > 0) parts.push(`${r.skills} skills`);
}
const totalSkills = r.skillDirectories || (r.workflows || 0) + (r.tasks || 0) + (r.tools || 0) + (r.skills || 0);
if (totalSkills > 0) parts.push(`${totalSkills} skills`);
if (r.agents > 0) parts.push(`${r.agents} agents`);
detail = parts.join(', ');
}
// Propagate handler's success status (default true for backward compat)