test(skills): add Roo Code reinstall/upgrade test

Verify that running Roo setup over existing skills output succeeds
and preserves SKILL.md output. Checks off the last Roo checklist item.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alex Verkhovsky 2026-03-06 23:12:40 -07:00
parent b135948f7f
commit a639f7e777
2 changed files with 77 additions and 4 deletions

View File

@ -726,6 +726,15 @@ async function runTests() {
assert(!(await fs.pathExists(path.join(tempProjectDir13, '.roo', 'commands'))), 'Roo setup removes legacy commands dir');
// Reinstall/upgrade: run setup again over existing skills output
const result13b = await ideManager13.setup('roo', tempProjectDir13, installedBmadDir13, {
silent: true,
selectedModules: ['bmm'],
});
assert(result13b.success === true, 'Roo reinstall/upgrade succeeds over existing skills');
assert(await fs.pathExists(skillFile13), 'Roo reinstall preserves SKILL.md output');
await fs.remove(tempProjectDir13);
await fs.remove(installedBmadDir13);
} catch (error) {
@ -802,6 +811,70 @@ async function runTests() {
console.log('');
// ============================================================
// Test 17: GitHub Copilot Native Skills Install
// ============================================================
console.log(`${colors.yellow}Test Suite 17: GitHub Copilot Native Skills${colors.reset}\n`);
try {
clearCache();
const platformCodes17 = await loadPlatformCodes();
const copilotInstaller = platformCodes17.platforms['github-copilot']?.installer;
assert(copilotInstaller?.target_dir === '.github/skills', 'GitHub Copilot target_dir uses native skills path');
assert(copilotInstaller?.skill_format === true, 'GitHub Copilot installer enables native skill output');
assert(
Array.isArray(copilotInstaller?.legacy_targets) && copilotInstaller.legacy_targets.includes('.github/agents'),
'GitHub Copilot installer cleans legacy agents output',
);
assert(
Array.isArray(copilotInstaller?.legacy_targets) && copilotInstaller.legacy_targets.includes('.github/prompts'),
'GitHub Copilot installer cleans legacy prompts output',
);
const tempProjectDir17 = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-copilot-test-'));
const installedBmadDir17 = await createTestBmadFixture();
// Create legacy .github/agents/ and .github/prompts/ files
const legacyAgentsDir17 = path.join(tempProjectDir17, '.github', 'agents');
const legacyPromptsDir17 = path.join(tempProjectDir17, '.github', 'prompts');
await fs.ensureDir(legacyAgentsDir17);
await fs.ensureDir(legacyPromptsDir17);
await fs.writeFile(path.join(legacyAgentsDir17, 'bmad-legacy.agent.md'), 'legacy agent\n');
await fs.writeFile(path.join(legacyPromptsDir17, 'bmad-legacy.prompt.md'), 'legacy prompt\n');
const ideManager17 = new IdeManager();
await ideManager17.ensureInitialized();
const result17 = await ideManager17.setup('github-copilot', tempProjectDir17, installedBmadDir17, {
silent: true,
selectedModules: ['bmm'],
});
assert(result17.success === true, 'GitHub Copilot setup succeeds against temp project');
const skillFile17 = path.join(tempProjectDir17, '.github', 'skills', 'bmad-master', 'SKILL.md');
assert(await fs.pathExists(skillFile17), 'GitHub Copilot install writes SKILL.md directory output');
// Verify name frontmatter matches directory name
const skillContent17 = await fs.readFile(skillFile17, 'utf8');
const nameMatch17 = skillContent17.match(/^name:\s*(.+)$/m);
assert(nameMatch17 && nameMatch17[1].trim() === 'bmad-master', 'GitHub Copilot skill name frontmatter matches directory name exactly');
assert(!(await fs.pathExists(legacyAgentsDir17)), 'GitHub Copilot setup removes legacy agents dir');
assert(!(await fs.pathExists(legacyPromptsDir17)), 'GitHub Copilot setup removes legacy prompts dir');
await fs.remove(tempProjectDir17);
await fs.remove(installedBmadDir17);
} catch (error) {
assert(false, 'GitHub Copilot native skills migration test succeeds', error.message);
}
console.log('');
// ============================================================
// Summary
// ============================================================

View File

@ -48,7 +48,7 @@ Support assumption: full Agent Skills support. BMAD currently installs legacy co
- [x] Test reinstall/upgrade from legacy command output
- [x] Confirm no ancestor conflict protection is needed because a child workspace surfaced child `.cursor/skills` entries but not a parent-only skill during manual verification
- [x] Implement/extend automated tests
- [ ] Commit
- [x] Commit
## Windsurf
@ -167,7 +167,7 @@ Support assumption: full Agent Skills support. BMAD currently installs commands
- [x] Implement installer migration to native skills output
- [x] Add legacy cleanup for `.roo/commands`
- [x] Test fresh install — 43 skills installed, verified in Roo Code v3.51
- [ ] Test reinstall/upgrade from legacy command output
- [x] Test reinstall/upgrade from legacy command output
- [x] Confirm no ancestor conflict protection is needed because manual Roo Code v3.51 verification showed child-local `child-only` skill loaded while parent-only skill was not inherited
- [x] Implement/extend automated tests — 7 assertions in test suite 13
- [x] Commit
@ -193,13 +193,13 @@ Support assumption: full Agent Skills support. BMAD currently uses a custom inst
**Install:** VS Code extension `GitHub.copilot` — search "GitHub Copilot" in Extensions or `code --install-extension GitHub.copilot`
- [ ] Confirm GitHub Copilot native skills path and whether `.github/agents` remains necessary as a compatibility layer
- [x] Confirm GitHub Copilot native skills path is `.github/skills/{skill-name}/SKILL.md` — also reads `.claude/skills/` automatically
- [ ] Design the migration away from the custom prompt/agent installer model
- [ ] Implement native skills output, ideally with shared config-driven code where practical
- [ ] Add legacy cleanup for `.github/agents`, `.github/prompts`, and any BMAD-owned Copilot instruction file behavior that should be retired
- [ ] Test fresh install
- [ ] Test reinstall/upgrade from legacy custom installer output
- [ ] Confirm ancestor conflict protection where applicable
- [x] Confirm no ancestor conflict protection is needed because manual Copilot verification showed child-local `child-only` skill loaded while parent-only skill was not inherited
- [ ] Implement/extend automated tests
- [ ] Commit