feat(skills): migrate all remaining platforms to native skills format#1841
feat(skills): migrate all remaining platforms to native skills format#1841alexeyv merged 18 commits intobmad-code-org:mainfrom
Conversation
|
@coderabbitai review |
🤖 Augment PR SummarySummary: This PR completes a broad migration from legacy “commands/workflows/agents/prompts” installers to native Changes:
Technical Notes: The migration relies on 🤖 Was this summary useful? React with 👍 or 👎 |
📝 WalkthroughWalkthroughThis PR migrates IDE installation from custom modules to a config-driven approach, removing platform-specific installers for GitHub Copilot, KiloCoder, and Rovo Dev. It consolidates their functionality into unified cleanup methods and platform configuration entries, adds suspension checks to prevent installing unsupported platforms, and expands test coverage for multiple platform scenarios including legacy artifact cleanup and reinstall paths. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 15
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
tools/cli/installers/lib/core/installer.js (2)
1238-1242:⚠️ Potential issue | 🟠 MajorIDE setup failures never affect the install result.
Failed IDE setups only add an error line to the summary;
install()still returns{ success: true }. Callers and automation will treat the run as successful even when one of the requested IDE migrations failed.Also applies to: 1340-1346
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/core/installer.js` around lines 1238 - 1242, The installer currently treats individual IDE setup failures as non-fatal because it only calls addResult(ide, ...) with setupResult but doesn't propagate failure to the install() return; update the logic in install() (and the similar block around the other occurrence) to maintain an overallSuccess boolean initialized true, set overallSuccess = false whenever setupResult.success is false (where addResult is called), and return { success: overallSuccess, ... } (or incorporate overallSuccess into the existing return) so callers receive a failing result when any IDE setup fails; ensure both the block using addResult(ide, 'error', setupResult.error || 'failed') and the mirrored block at the other location update the overall success flag.
1227-1236:⚠️ Potential issue | 🟠 MajorPersist IDE config only after setup succeeds.
saveIdeConfig()runs before the success check. A suspended or otherwise failed IDE now gets recorded as configured, which means later updates will try to preserve state that never installed correctly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/core/installer.js` around lines 1227 - 1236, The IDE config is being persisted before verifying setup succeeded: move the call to this.ideConfigManager.saveIdeConfig(bmadDir, ide, ideConfigurations[ide]) so it runs only after verifying the setupResult from await this.ideManager.setup(ide, ...) indicates success (e.g., check setupResult.success or that setupResult is truthy/non-error), or alternatively wrap the setup call in try/catch and save the config only in the successful path inside the try; reference the variables setupResult, this.ideManager.setup, this.ideConfigManager.saveIdeConfig, and ideConfigurations[ide] when making the change.tools/docs/native-skills-migration-checklist.md (1)
3-5:⚠️ Potential issue | 🟡 MinorUpdate the branch reference at the top of the checklist.
The PR metadata says this work is coming from
all-is-skills-2, but the document still points readers atrefactor/all-is-skills. That sends anyone auditing the migration to the wrong branch.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/docs/native-skills-migration-checklist.md` around lines 3 - 5, Update the branch reference string at the top of the checklist so it matches the PR metadata: replace the text "refactor/all-is-skills" with "all-is-skills-2" (the branch named in the PR) in the document header, and verify any other occurrences of the branch identifier in "native-skills-migration-checklist.md" are updated to the same "all-is-skills-2" value so readers are directed to the correct branch.
🧹 Nitpick comments (5)
tools/cli/installers/lib/ide/manager.js (1)
47-65: Delete the inert custom-installer pass.
loadHandlers()still callsloadCustomInstallerFiles(), butcustomFilesis hard-coded to[]and the nearby comments still mention removed installers. Leaving a dead branch in the core loader is how migration behavior and documentation drift apart again.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/ide/manager.js` around lines 47 - 65, Remove the inert custom-installer pass: update loadHandlers() to stop calling loadCustomInstallerFiles() and only invoke loadConfigDrivenHandlers(), then delete the unused loadCustomInstallerFiles() method (and its comments/variable customFiles) from the file; ensure no other code references loadCustomInstallerFiles() and adjust comments so the loader reflects that installers are now config-driven (use loadHandlers, loadConfigDrivenHandlers, loadCustomInstallerFiles, and customFiles as search handles).tools/cli/installers/lib/ide/_config-driven.js (1)
658-671: The shared installer is accumulating platform-specific branches again.These
this.name === ...checks reintroduce per-IDE logic into the generic path. The next migration with an auxiliary cleanup file will require editing_config-driven.jsinstead of just extendingplatform-codes.yaml, which defeats the config-driven boundary this PR is trying to establish.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/ide/_config-driven.js` around lines 658 - 671, The generic installer is doing platform-specific branching (this.name === 'github-copilot' / 'kilo' / 'rovo-dev') inside _config-driven.js; remove those hard-coded checks and instead drive cleanup invocation from the configuration (platform-codes.yaml) so the installer remains generic: add per-platform cleanup hooks/flags in platform-codes.yaml, read that mapping in the existing config-driven flow, and call the appropriate cleanup helper functions (cleanupCopilotInstructions, cleanupKiloModes, cleanupRovoDevPrompts) only when the config for the current installer indicates it — e.g., map installer names to cleanup actions in the config and loop over configured actions rather than using inline this.name conditionals.test/test-installation-components.js (3)
480-503: Usefinallyfor temp fixture cleanup.
tempProjectDir9andinstalledBmadDir9are only removed on the happy path. Ifsetup()or any later filesystem read throws, this leaks temp trees into local and CI runs. The same pattern is repeated throughout the new suites.Suggested shape
- try { - const tempProjectDir9 = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-claude-code-test-')); - const installedBmadDir9 = await createTestBmadFixture(); + let tempProjectDir9; + let installedBmadDir9; + try { + tempProjectDir9 = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-claude-code-test-')); + installedBmadDir9 = await createTestBmadFixture(); // ... - await fs.remove(tempProjectDir9); - await fs.remove(installedBmadDir9); } catch (error) { assert(false, 'Claude Code native skills migration test succeeds', error.message); + } finally { + await Promise.allSettled([ + tempProjectDir9 ? fs.remove(tempProjectDir9) : Promise.resolve(), + installedBmadDir9 ? fs.remove(installedBmadDir9) : Promise.resolve(), + ]); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/test-installation-components.js` around lines 480 - 503, The test currently only removes tempProjectDir9 and installedBmadDir9 on the success path, risking leaked temp files; wrap the teardown in a finally block so cleanup always runs: move the await fs.remove(tempProjectDir9) and await fs.remove(installedBmadDir9) into a finally after the try/catch that creates tempProjectDir9 and installedBmadDir9 and calls IdeManager().ensureInitialized() and ideManager9.setup(...), ensuring both variables are declared in a scope visible to the finally and that cleanup guards against undefined values.
460-1468: Stop cloning the same suite 19 times.These blocks are already drifting: some platforms verify frontmatter/name sync, some verify reinstall, some pin ancestor behavior, and others skip those checks entirely. This needs a table-driven helper so every migrated platform gets the same contract instead of another copy-pasted variant.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/test-installation-components.js` around lines 460 - 1468, The test file duplicates nearly identical "native skills" suites; replace the repeated blocks with a single table-driven helper (e.g., runNativeSkillsTest or runPlatformNativeSkillsTest) that accepts platform key, expected installer properties, and optional checks; iterate over a platforms array instead of cloning suites. Specifically, consolidate the repeated uses of loadPlatformCodes(), clearCache(), createTestBmadFixture(), new IdeManager().setup(), and assertions around installer.target_dir, installer.skill_format, installer.legacy_targets, SKILL.md existence, legacy cleanup and optional frontmatter/reinstall checks into one helper and call it for each platform (use the current variable names like platformCodes19/codebuddyInstaller as examples when migrating assertions). Ensure the helper supports flags for ancestor-conflict checks, name-frontmatter verification, reinstall verification, and special legacy-file mutations (e.g., copilot-instructions.md, prompts.yml) so all platforms run the same contract-driven tests.
1408-1460: Add the Codex variant forbmad-os-*preservation.This only exercises
.claude/skills. Codex uses.agents/skills, so platform-specific cleanup regressions there are untested even though the same preservation rule matters for that path too.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/test-installation-components.js` around lines 1408 - 1460, The test only covers preservation under .claude/skills; add the Codex variant that exercises .agents/skills so bmad-os-* preservation is validated for Codex too: create parallel directories (e.g., osAgentSkillDir27 and osAgentSkillDir27b under tempProjectDir27 + '.agents/skills' with SKILL.md files), add a regular bmad skill under '.agents/skills' to be cleaned, invoke IdeManager.setup with 'codex' (or run a separate setup call like the existing Claude one) and assert the .agents/skills bmad-os-* dirs still exist, their contents are unchanged, and fresh bmad skills were installed for Codex (use the same variable naming pattern such as tempProjectDir27, installedBmadDir27, ideManager27/result27 to locate the test code to modify).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/test-installation-components.js`:
- Around line 686-698: The tests for Roo, Copilot, and Cline are missing
assertions that ancestor checks remain disabled; update the test blocks that use
loadPlatformCodes() and inspect
platformCodes13.platforms.{roo,copilot,cline}.installer to add assertions that
installer.ancestor_conflict_check === false (or explicitly === false using
optional chaining, e.g., rooInstaller?.ancestor_conflict_check === false) with a
clear failure message so regressions that enable ancestor checks are caught;
apply the same pattern to the other similar test sections that inspect copilot
and cline (the blocks around the other mentioned ranges).
- Around line 495-498: Several native-skill test cases are missing the assertion
that the SKILL.md frontmatter "name:" matches the skill directory name; update
the failing test blocks (the ones creating skillFile9/tempProjectDir9/legacyDir9
and the other listed suites) to read and parse the SKILL.md frontmatter and
assert that the "name" field equals the skill directory basename (use the same
tempProjectDirX and skillFileX variables to locate files and derive directory
names), so each suite (Claude Code, Codex, Cursor, iFlow, QwenCoder, Rovo Dev
and the other referenced blocks) enforces the name/frontmatter invariant.
- Around line 488-491: The tests call ideManager9.setup(..., { selectedModules:
['bmm'] }) but only assert presence of the core "bmad-master" artifact, so
update each affected test (e.g., the block using result9, ideManager9,
tempProjectDir9, installedBmadDir9) to assert that the selected module artifact
for "bmm" is installed and that at least one artifact from an unselected module
is absent; specifically, after the setup call for result9 check that the bmm
fixture artifact (the expected file/directory name produced by the bmm fixture)
exists inside installedBmadDir9 (or the installed path derived from result9) and
assert that an artifact belonging to a module not in selectedModules is not
present. Ensure you make the same assertions in all listed test blocks (lines
around 576-579, 661-664, 709-712, etc.) referencing their respective
result/ideManager/tempProjectDir/installedBmadDir variables.
- Around line 729-736: The test currently only asserts that the second setup
(ideManager13.setup producing result13b) succeeded and that skillFile13 still
exists; change it to verify idempotency by capturing the initial setup result
(e.g., result13 or the first run's filesystem snapshot) and then comparing the
second run to that baseline: assert result fields are equal (success,
created/updated lists) and assert the skill directory contents and file
checksums/contents (skillFile13 and any generated skill directories) are
identical and no duplicate directories or stale files were introduced; apply the
same pattern for the other affected cases (the tests around lines 941-948,
1002-1008, 1062-1068, 1121-1127, 1238-1244) by replacing simple existence checks
with strict equality/content comparisons and duplicate-file detection.
- Around line 526-537: Add assertions to these conflict-path tests to verify no
partial install occurred: after the setup call (e.g. result10), assert that the
child project did not get any of the installer-created dirs (check that
path.join(childProjectDir10, '.claude/skills'), path.join(childProjectDir10,
'.agents/skills'), and path.join(childProjectDir10, '.opencode/skills') do NOT
exist) and/or assert that installedBmadDir10 was not created/modified; do the
same for the other test blocks referenced (the ones around lines 614-623 and
764-775) using their local variables (e.g. resultX, childProjectDirX,
installedBmadDirX) so each conflict test asserts both ancestor-conflict and that
no partial installation artifacts are present.
- Around line 1432-1460: Add an assertion that the seeded stale regular BMAD
skill directory/file (regularSkillDir27 or specifically the 'bmad-architect'
SKILL.md) does not exist after running IdeManager.setup; i.e., after calling
ideManager27.setup(...) assert that the old bmad-architect skill was removed
(use fs.pathExists on regularSkillDir27 or path.join(tempProjectDir27,
'.claude','skills','bmad-architect','SKILL.md') and assert it returns false) so
the test verifies the cleanup removed the stale generated skill before fresh
install.
- Around line 1367-1399: The test only asserts the remaining prompt's name, so
extend the verification after calling IdeManager.setup (the result26 and
cleanedPrompts26 checks) to assert the full user prompt object is preserved:
check description and content_file (and any other original keys) match the
original promptsContent26 entry rather than only the name; in other words,
compare cleanedPrompts26.prompts[0] to the original user prompt object from
promptsContent26 (or assert individual fields like description and content_file)
to ensure no keys were lost or rewritten.
- Around line 849-885: The test currently only checks for absence of BMAD
markers and presence of two user strings, which is too loose; replace that with
a strict equality check against the exact expected post-cleanup content. After
reading cleanedInstructions17, build an expected string (e.g. const
expectedInstructions17 = 'User content before\nUser content after\n') and assert
cleanedInstructions17 === expectedInstructions17 (or use assert.strictEqual) so
the test fails if lines are duplicated, reordered, or extra garbage remains;
reference cleanedInstructions17 and copilotInstructionsPath17 to locate and
update the assertions.
In `@tools/cli/installers/lib/core/installer.js`:
- Around line 723-725: Normalize IDE keys before checking suspension: when
building suspendedIdes from config.ides, apply the same normalization used in
IdeManager.setup (e.g., lowercase) to each ide before calling
this.ideManager.handlers.get(ide); replace the direct lookup
this.ideManager.handlers.get(ide) with a normalized key (such as
ide.toLowerCase() or the shared normalizer function) so mixed-case IDs are
correctly matched to suspended entries and cannot bypass the suspended-only
abort.
- Around line 728-735: When detecting that all selected IDEs are suspended (the
suspendedIdes check using suspendedIdes, this.ideManager.handlers and
prompts.log.error), remove the temporary backup directories created earlier
before throwing: call the existing cleanup/rollback helper used in the catch
path (or add a small helper like removeTempBackupDirs) to delete
`_bmad-custom-backup-temp` and `_bmad-modified-backup-temp` (use fs.promises.rm
or equivalent with recursive:true, force:true), catch and log any cleanup errors
(prompts.log.warn) and only then throw the Error; do not leave temp backups
behind.
In `@tools/cli/installers/lib/ide/_config-driven.js`:
- Around line 883-889: The code currently removes prompts.yml when removedCount
> 0 and config.prompts.length === 0, which can delete unrelated top-level user
metadata; instead, load the existing prompts file (promptsPath) and
merge/compare with the new config so you only remove the "prompts" key or the
BMAD entries, then write back the resulting object with yaml.stringify via
fs.writeFile; only call fs.remove(promptsPath) if the resulting file object has
no other top-level keys left (i.e., truly empty) — update the logic in the block
that references removedCount, config.prompts, promptsPath, fs.remove and
fs.writeFile to preserve any non-prompts data.
- Around line 791-818: The cleanupCopilotInstructions function performs multiple
filesystem operations (fs.readFile, fs.remove, fs.rename, fs.writeFile,
fs.pathExists) that can throw and currently bubble up; make this best-effort by
wrapping the body in a try/catch (or wrapping each risky section) to catch
errors, log a non-fatal warning via prompts.log.message (or process logger) when
an operation fails, and avoid rethrowing so IDE setup continues; keep the
existing behavior (restoring backups, deleting backups, and final success
message) when operations succeed but ensure any thrown errors during cleanup are
caught and reported as warnings rather than failing the whole process.
In `@tools/cli/installers/lib/ide/manager.js`:
- Around line 185-193: The suspended-platform cleanup runs outside the existing
failure boundary and can throw from handler.cleanup, causing IdeManager.setup to
throw instead of returning the suspended result; wrap the suspended branch's
cleanup call in the same try/catch used for normal setup (or add a local
try/catch around handler.cleanup) so any errors from handler.cleanup are caught
and do not propagate, log the error (respecting options.silent) and ensure
IdeManager.setup still returns the suspended result (referencing
IdeManager.setup and handler.cleanup to locate the code).
In `@tools/cli/installers/lib/ide/platform-codes.yaml`:
- Around line 207-217: The installer metadata still uses the retired product
name "Roo Cline"; update the platform entry keyed by roo so its name and any
user-facing strings reflect the new product name "Roo Code" (e.g., change the
name field from "Roo Cline" to "Roo Code" and update the description if needed)
so the picker, summaries, and warnings show the correct current name.
In `@tools/docs/native-skills-migration-checklist.md`:
- Around line 220-224: The install command in the Gemini CLI docs uses the wrong
package name; update the install instruction that currently shows `npm install
-g `@anthropic-ai/gemini-cli`` to use Google's official package `npm install -g
`@google/gemini-cli`` so the Gemini CLI install step in the "Gemini CLI" section
is correct; ensure the text around "Install:" is updated to reference
`@google/gemini-cli`.
---
Outside diff comments:
In `@tools/cli/installers/lib/core/installer.js`:
- Around line 1238-1242: The installer currently treats individual IDE setup
failures as non-fatal because it only calls addResult(ide, ...) with setupResult
but doesn't propagate failure to the install() return; update the logic in
install() (and the similar block around the other occurrence) to maintain an
overallSuccess boolean initialized true, set overallSuccess = false whenever
setupResult.success is false (where addResult is called), and return { success:
overallSuccess, ... } (or incorporate overallSuccess into the existing return)
so callers receive a failing result when any IDE setup fails; ensure both the
block using addResult(ide, 'error', setupResult.error || 'failed') and the
mirrored block at the other location update the overall success flag.
- Around line 1227-1236: The IDE config is being persisted before verifying
setup succeeded: move the call to this.ideConfigManager.saveIdeConfig(bmadDir,
ide, ideConfigurations[ide]) so it runs only after verifying the setupResult
from await this.ideManager.setup(ide, ...) indicates success (e.g., check
setupResult.success or that setupResult is truthy/non-error), or alternatively
wrap the setup call in try/catch and save the config only in the successful path
inside the try; reference the variables setupResult, this.ideManager.setup,
this.ideConfigManager.saveIdeConfig, and ideConfigurations[ide] when making the
change.
In `@tools/docs/native-skills-migration-checklist.md`:
- Around line 3-5: Update the branch reference string at the top of the
checklist so it matches the PR metadata: replace the text
"refactor/all-is-skills" with "all-is-skills-2" (the branch named in the PR) in
the document header, and verify any other occurrences of the branch identifier
in "native-skills-migration-checklist.md" are updated to the same
"all-is-skills-2" value so readers are directed to the correct branch.
---
Nitpick comments:
In `@test/test-installation-components.js`:
- Around line 480-503: The test currently only removes tempProjectDir9 and
installedBmadDir9 on the success path, risking leaked temp files; wrap the
teardown in a finally block so cleanup always runs: move the await
fs.remove(tempProjectDir9) and await fs.remove(installedBmadDir9) into a finally
after the try/catch that creates tempProjectDir9 and installedBmadDir9 and calls
IdeManager().ensureInitialized() and ideManager9.setup(...), ensuring both
variables are declared in a scope visible to the finally and that cleanup guards
against undefined values.
- Around line 460-1468: The test file duplicates nearly identical "native
skills" suites; replace the repeated blocks with a single table-driven helper
(e.g., runNativeSkillsTest or runPlatformNativeSkillsTest) that accepts platform
key, expected installer properties, and optional checks; iterate over a
platforms array instead of cloning suites. Specifically, consolidate the
repeated uses of loadPlatformCodes(), clearCache(), createTestBmadFixture(), new
IdeManager().setup(), and assertions around installer.target_dir,
installer.skill_format, installer.legacy_targets, SKILL.md existence, legacy
cleanup and optional frontmatter/reinstall checks into one helper and call it
for each platform (use the current variable names like
platformCodes19/codebuddyInstaller as examples when migrating assertions).
Ensure the helper supports flags for ancestor-conflict checks, name-frontmatter
verification, reinstall verification, and special legacy-file mutations (e.g.,
copilot-instructions.md, prompts.yml) so all platforms run the same
contract-driven tests.
- Around line 1408-1460: The test only covers preservation under .claude/skills;
add the Codex variant that exercises .agents/skills so bmad-os-* preservation is
validated for Codex too: create parallel directories (e.g., osAgentSkillDir27
and osAgentSkillDir27b under tempProjectDir27 + '.agents/skills' with SKILL.md
files), add a regular bmad skill under '.agents/skills' to be cleaned, invoke
IdeManager.setup with 'codex' (or run a separate setup call like the existing
Claude one) and assert the .agents/skills bmad-os-* dirs still exist, their
contents are unchanged, and fresh bmad skills were installed for Codex (use the
same variable naming pattern such as tempProjectDir27, installedBmadDir27,
ideManager27/result27 to locate the test code to modify).
In `@tools/cli/installers/lib/ide/_config-driven.js`:
- Around line 658-671: The generic installer is doing platform-specific
branching (this.name === 'github-copilot' / 'kilo' / 'rovo-dev') inside
_config-driven.js; remove those hard-coded checks and instead drive cleanup
invocation from the configuration (platform-codes.yaml) so the installer remains
generic: add per-platform cleanup hooks/flags in platform-codes.yaml, read that
mapping in the existing config-driven flow, and call the appropriate cleanup
helper functions (cleanupCopilotInstructions, cleanupKiloModes,
cleanupRovoDevPrompts) only when the config for the current installer indicates
it — e.g., map installer names to cleanup actions in the config and loop over
configured actions rather than using inline this.name conditionals.
In `@tools/cli/installers/lib/ide/manager.js`:
- Around line 47-65: Remove the inert custom-installer pass: update
loadHandlers() to stop calling loadCustomInstallerFiles() and only invoke
loadConfigDrivenHandlers(), then delete the unused loadCustomInstallerFiles()
method (and its comments/variable customFiles) from the file; ensure no other
code references loadCustomInstallerFiles() and adjust comments so the loader
reflects that installers are now config-driven (use loadHandlers,
loadConfigDrivenHandlers, loadCustomInstallerFiles, and customFiles as search
handles).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7e484601-5b88-4111-ad02-b533bc8cb94d
📒 Files selected for processing (9)
test/test-installation-components.jstools/cli/installers/lib/core/installer.jstools/cli/installers/lib/ide/_config-driven.jstools/cli/installers/lib/ide/github-copilot.jstools/cli/installers/lib/ide/kilo.jstools/cli/installers/lib/ide/manager.jstools/cli/installers/lib/ide/platform-codes.yamltools/cli/installers/lib/ide/rovodev.jstools/docs/native-skills-migration-checklist.md
💤 Files with no reviewable changes (3)
- tools/cli/installers/lib/ide/rovodev.js
- tools/cli/installers/lib/ide/kilo.js
- tools/cli/installers/lib/ide/github-copilot.js
Move Roo Code from legacy `.roo/commands/` flat files to native
`.roo/skills/{skill-name}/SKILL.md` directory output. Verified
skill discovery in Roo Code v3.51 with 43 skills installed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add dedicated test suites covering config validation, fresh install, legacy cleanup, and ancestor conflict detection for Claude Code, Codex CLI, and Cursor. Updates migration checklist to reflect verified status. 84 assertions now pass (up from 50). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Replace 699-line custom installer with config-driven skill_format.
Output moves from .github/agents/ + .github/prompts/ to
.github/skills/{skill-name}/SKILL.md. Legacy cleanup strips BMAD
markers from copilot-instructions.md and removes old directories.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Cline installer from .clinerules/workflows to .cline/skills with SKILL.md directory output. Add legacy cleanup and 9 test assertions.
Move CodeBuddy installer from .codebuddy/commands to .codebuddy/skills with SKILL.md directory output. Add legacy cleanup and 9 test assertions.
Move Crush installer from .crush/commands to .crush/skills with SKILL.md directory output. Add legacy cleanup and 9 test assertions.
Move Trae installer from .trae/rules to .trae/skills with SKILL.md directory output. Add legacy cleanup and 9 test assertions.
Replace 269-line custom kilo.js installer with config-driven entry in platform-codes.yaml targeting .kilocode/skills/ with skill_format: true. - Add installer config: target_dir, skill_format, template_type, legacy_targets - Add cleanupKiloModes() to strip BMAD modes from .kilocodemodes on cleanup - Remove kilo.js from manager.js customFiles and Kilo-specific result handling - Delete tools/cli/installers/lib/ide/kilo.js - Add test Suite 22: 11 assertions (config, install, legacy cleanup, modes, reinstall) - Update migration checklist with verified results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace TOML-based .gemini/commands output with native SKILL.md output in .gemini/skills/. Gemini CLI confirms native skills support per geminicli.com/docs/cli/skills/. - Update platform-codes.yaml: target_dir, skill_format, legacy_targets - Add test Suite 23: 9 assertions (config, install, legacy, reinstall) - Add Gemini CLI section to migration checklist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete the native skills migration for all remaining platforms: - iFlow: .iflow/commands → .iflow/skills (config change) - QwenCoder: .qwen/commands → .qwen/skills (config change) - Rovo Dev: replace 257-line custom rovodev.js with config-driven .rovodev/skills, add cleanupRovoDevPrompts() for prompts.yml cleanup All platforms now use config-driven native skills. No custom installer files remain. Manager.js customFiles array is now empty. - Add test suites 24-26: 20 new assertions (173 total) - Update migration checklist: all summary gates passed - Delete tools/cli/installers/lib/ide/rovodev.js Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cleanupTarget method removed all entries starting with "bmad" from IDE skills directories, which would also wipe version-controlled bmad-os-* skills from the BMAD-METHOD repo. Add exclusion for the bmad-os- prefix so those skills survive reinstalls.
Add NEEDS MANUAL IDE VERIFICATION to KiloCoder, Gemini CLI, iFlow, QwenCoder, and Rovo Dev checklists. CodeBuddy, Crush, and Trae already had the flag.
Kilo Code does not support the Agent Skills standard — the migration from modes+workflows to skills was based on a false fork assumption. - Add suspended field to platform-codes.yaml, hiding Kilo from the IDE picker and blocking setup with a clear message - Fail the installer early (before writing _bmad/) if all selected IDEs are suspended, protecting existing installations from being corrupted - Still clean up legacy Kilo artifacts (.kilocodemodes, .kilocode/workflows) when users switch to a different IDE - Mark Crush and Gemini CLI as manually verified (both work end-to-end) - Replace Suite 22 install tests with suspended-behavior tests (7 assertions)
Drop the bmm module prefix from 6 workflow skill names so they install as bmad-create-prd, bmad-domain-research, etc. instead of bmad-bmm-create-prd, bmad-bmm-domain-research, etc.
Triage of 18 findings from Augment and CodeRabbit reviews on PR bmad-code-org#1841: Source code fixes: - Exclude bmad-os-* from findAncestorConflict to match cleanupTarget - Wrap cleanupCopilotInstructions in try/catch (best-effort, not fatal) - Wrap suspended-platform cleanup in try/catch (failure boundary) - Clean up temp backup dirs in catch block when install aborts - Normalize IDE keys to lowercase before suspended lookup - Delete dead loadCustomInstallerFiles method and stale references - Rename "Roo Cline" to "Roo Code" in both platform-codes.yaml files - Fix Gemini CLI package name (@google/gemini-cli, not @Anthropic-AI) Test improvements: - Add name/frontmatter invariant check to 6 missing platform suites - Assert stale bmad-architect skill is removed after cleanup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Platforms
.roo/commands.roo/skills.github/agents,.github/prompts.github/skills.clinerules/workflows.cline/skills.codebuddy/commands.codebuddy/skills.crush/commands.crush/skills.trae/rules.trae/skills.kilocode/workflows.kilocode/skills.gemini/commands.gemini/skills.iflow/commands.iflow/skills.qwen/commands.qwen/skills.rovodev/workflows.rovodev/skillsTest plan
🤖 Generated with Claude Code