Skip to content

feat(skills): migrate all remaining platforms to native skills format#1841

Merged
alexeyv merged 18 commits intobmad-code-org:mainfrom
alexeyv:all-is-skills-2
Mar 7, 2026
Merged

feat(skills): migrate all remaining platforms to native skills format#1841
alexeyv merged 18 commits intobmad-code-org:mainfrom
alexeyv:all-is-skills-2

Conversation

@alexeyv
Copy link
Copy Markdown
Collaborator

@alexeyv alexeyv commented Mar 7, 2026

Summary

  • Migrate all remaining platforms to the native Agent Skills format (SKILL.md in directories)
  • Platforms migrated: Roo Code, GitHub Copilot, Cline, CodeBuddy, Crush, Trae, KiloCoder, Gemini CLI, iFlow, QwenCoder, Rovo Dev
  • Suspend KiloCoder (does not yet support Agent Skills standard)
  • Preserve bmad-os-* skills during cleanup
  • Add test coverage across multiple test suites (all 106 tests pass)

Platforms

Platform Legacy path New path Status
Roo Code .roo/commands .roo/skills Migrated
GitHub Copilot .github/agents, .github/prompts .github/skills Migrated
Cline .clinerules/workflows .cline/skills Migrated
CodeBuddy .codebuddy/commands .codebuddy/skills Migrated
Crush .crush/commands .crush/skills Migrated
Trae .trae/rules .trae/skills Migrated
KiloCoder .kilocode/workflows .kilocode/skills Suspended
Gemini CLI .gemini/commands .gemini/skills Migrated
iFlow .iflow/commands .iflow/skills Migrated
QwenCoder .qwen/commands .qwen/skills Migrated
Rovo Dev .rovodev/workflows .rovodev/skills Migrated

Test plan

  • All 106 installation component tests pass
  • Schema validation, linting, formatting all pass
  • Live install verified for migrated platforms
  • Legacy cleanup verified
  • Reinstall/upgrade verified

🤖 Generated with Claude Code

@alexeyv alexeyv marked this pull request as ready for review March 7, 2026 16:49
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 7, 2026

@coderabbitai review

@alexeyv alexeyv changed the title feat(skills): migrate Roo Code, GitHub Copilot, and Cline to native skills feat(skills): migrate all remaining platforms to native skills format Mar 7, 2026
@augmentcode
Copy link
Copy Markdown

augmentcode bot commented Mar 7, 2026

🤖 Augment PR Summary

Summary: This PR completes a broad migration from legacy “commands/workflows/agents/prompts” installers to native SKILL.md-based skill directories across multiple platforms.

Changes:

  • Migrates Roo Code, GitHub Copilot, Cline, and several other platforms to config-driven native skills output (.../skills/<skill-name>/SKILL.md).
  • Removes large custom installers for GitHub Copilot, Kilo, and Rovo Dev in favor of platform-codes.yaml configuration.
  • Adds targeted legacy cleanup helpers: Copilot instruction marker stripping, Kilo .kilocodemodes cleanup, and Rovo Dev prompts.yml BMAD-entry cleanup.
  • Preserves version-controlled bmad-os-* skills during cleanup while refreshing regular BMAD-installed skills.
  • Introduces a “suspended platform” mechanism (KiloCoder): hidden from IDE selection and blocked during setup with an explanatory message.
  • Adds an early installer guard to abort when all selected IDEs are suspended, preventing unintended _bmad/ upgrades without a usable IDE target.
  • Updates platform-codes.yaml to define new target_dir values and legacy_targets for migrated platforms.
  • Expands installation-component test coverage substantially, including fresh install, legacy cleanup, reinstall/upgrade, ancestor-conflict checks, and suspended-platform behavior.

Technical Notes: The migration relies on skill_format: true to drive directory-based skill output and consolidates cleanup/installation behavior into the config-driven IDE handler.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 5 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 7, 2026

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
IDE Module Consolidation
tools/cli/installers/lib/ide/github-copilot.js, tools/cli/installers/lib/ide/kilo.js, tools/cli/installers/lib/ide/rovodev.js
Removed 1,225 lines of custom IDE setup classes. Functionality consolidated into config-driven installer with cleanup hooks.
Config-Driven Installer Enhancement
tools/cli/installers/lib/ide/_config-driven.js
Added three new cleanup methods: cleanupCopilotInstructions, cleanupKiloModes, and cleanupRovoDevPrompts to strip BMAD-owned content. Enhanced target cleanup to preserve "bmad-os-\*" entries while removing other BMAD artifacts.
Installer Core and Manager
tools/cli/installers/lib/core/installer.js, tools/cli/installers/lib/ide/manager.js
Added fast-fail check for suspended IDEs post-selection. Reworked manager to use only config-driven handlers, skip suspended platforms in availability filtering, and apply cleanup logic for suspended installations.
Platform Configuration
tools/cli/installers/lib/ide/platform-codes.yaml
Updated 11+ platforms with legacy_targets, target directory migrations to .*\/skills, and skill_format flags. Added explicit installer blocks for GitHub Copilot and Rovo Dev. Marked KiloCoder as suspended with migration guidance.
Test Coverage Expansion
test/test-installation-components.js
Added 18 new test suites (Tests 9-27) covering platform-specific native skills installations, ancestor conflict handling, legacy cleanup verification, SKILL.md generation, and reinstall/upgrade paths across multiple platforms. Renamed Test 9 header.
Documentation Updates
tools/docs/native-skills-migration-checklist.md
Reorganized platform migration checklist with explicit Install blocks, updated legacy cleanup targets, adjusted test assertion counts, and marked KiloCoder as suspended. Updated summary gates for migration completion.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1834: Overlapping changes to platform-codes.yaml, config-driven installer pipeline, cleanup hooks, and skill-format/legacy_targets consolidation.
  • PR #1701: Conflicting rovodev installer implementation—main PR removes custom rovodev.js and migrates to config-driven, while related PR adds custom rovodev.js.
  • PR #1606: GitHub Copilot installer surface changes—related PR adds custom github-copilot.js handler while main PR consolidates it into config-driven approach.

Suggested reviewers

  • bmadcode
  • cecil-the-coder
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: migration of three platforms (Roo Code, GitHub Copilot, Cline) to native skills format, which is the primary objective clearly reflected in all modified files.
Description check ✅ Passed The description is directly related to the changeset, providing a clear summary of platform migrations, test coverage additions, and verification steps performed. It accurately reflects the core changes in the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🟠 Major

IDE 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 | 🟠 Major

Persist 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 | 🟡 Minor

Update 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 at refactor/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 calls loadCustomInstallerFiles(), but customFiles is 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.js instead of just extending platform-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: Use finally for temp fixture cleanup.

tempProjectDir9 and installedBmadDir9 are only removed on the happy path. If setup() 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 for bmad-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

📥 Commits

Reviewing files that changed from the base of the PR and between 434e7ef and e530a94.

📒 Files selected for processing (9)
  • test/test-installation-components.js
  • tools/cli/installers/lib/core/installer.js
  • tools/cli/installers/lib/ide/_config-driven.js
  • tools/cli/installers/lib/ide/github-copilot.js
  • tools/cli/installers/lib/ide/kilo.js
  • tools/cli/installers/lib/ide/manager.js
  • tools/cli/installers/lib/ide/platform-codes.yaml
  • tools/cli/installers/lib/ide/rovodev.js
  • tools/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

alexeyv and others added 18 commits March 7, 2026 12:27
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>
@alexeyv alexeyv merged commit 5aab72c into bmad-code-org:main Mar 7, 2026
5 checks passed
@alexeyv alexeyv deleted the all-is-skills-2 branch March 7, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant