Skip to content

fix(installer): preserve stale installed modules during update#2391

Merged
bmadcode merged 7 commits into
bmad-code-org:mainfrom
dickymoore:draft/preserve-stale-installed-modules
May 18, 2026
Merged

fix(installer): preserve stale installed modules during update#2391
bmadcode merged 7 commits into
bmad-code-org:mainfrom
dickymoore:draft/preserve-stale-installed-modules

Conversation

@dickymoore
Copy link
Copy Markdown
Contributor

@dickymoore dickymoore commented May 18, 2026

Summary

Fixes the update-time compatibility path for already-installed stale modules such as legacy Automator baut entries.

Changes

  • preserve installed modules whose source is no longer resolvable
  • preserve their config during modify/update and quick-update flows instead of dropping it or mis-scoping it

Why

This PR is about safe handling of existing installs. It prevents update flows from breaking or silently losing config when a previously installed module can no longer be resolved from current sources.

Scope limits

  • does not make Automator freshly installable again
  • does not add new module source resolution behavior
  • does not change registry metadata

Relationship To Other PRs

This PR is independent.

It solves the stale-install compatibility problem only. The separate “make Automator installable again” work is handled by:

  • BMAD-METHOD#2392 installer support for source_root
  • bmad-plugins-marketplace#26 registry metadata for Automator

Validation

  • node test/test-installation-components.js
  • full pre-commit suite passed during commit

@dickymoore
Copy link
Copy Markdown
Contributor Author

Addressed on the latest branch tip in 1541840ec.

The retained-module config fix now preserves prior [modules.<code>] blocks verbatim when a module is being kept installed but its schema source can no longer be resolved. That avoids the remaining quick-update drift where user-scoped values could be rewritten from _bmad/config.user.toml into _bmad/config.toml.

Scope is still intentionally narrow:

  • fresh unknown-schema modules keep the existing fallback behavior and still get a normal [modules.*] section
  • only retained modules with an existing prior block take the verbatim-preservation path
  • no install-layout or source-resolution expansion was added

Validation: node test/test-installation-components.js and the full pre-commit test/lint/format suite passed on commit.

@dickymoore
Copy link
Copy Markdown
Contributor Author

Cross-linking for review context:

  • This PR is the stale-install compatibility fix only.
  • It is independent of the fresh-installability work.
  • The separate “make Automator installable again” pair is:
    • BMAD-METHOD#2392
    • bmad-plugins-marketplace#26

Recommended merge order:

  • merge this PR independently
  • merge #26 and #2392 together, or #26 first and #2392 immediately after

@dickymoore dickymoore force-pushed the draft/preserve-stale-installed-modules branch from 76bf87c to 9cf7ba7 Compare May 18, 2026 12:19
@dickymoore dickymoore force-pushed the draft/preserve-stale-installed-modules branch from 9cf7ba7 to 3cdee79 Compare May 18, 2026 13:20
@dickymoore dickymoore marked this pull request as ready for review May 18, 2026 13:20
@github-actions
Copy link
Copy Markdown
Contributor

@coderabbitai review

@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 18, 2026

🤖 Augment PR Summary

Summary: Improves update/quick-update safety for installs that contain modules whose source can no longer be resolved (e.g., legacy/stale modules), preventing them from being removed or having their config/skills silently dropped.

Changes:

  • Passes a _preserveModules list through the update flows and excludes those modules from deselection removal.
  • Reads the prior skill-manifest.csv before regeneration and re-appends preserved-module rows after manifest generation.
  • Tracks files under preserved modules so files-manifest.csv continues to reflect those installations.
  • Adjusts IDE cleanup/install flow detection to treat a provided previousSkillIds set as the install/update signal.
  • Adds UI logic to detect installed modules that are no longer in official/registry/custom sources and warns when they are retained.

Technical Notes: The installer now threads preserved-module context into both module removal and manifest/IDE cleanup so legacy modules stay installed and keep their recorded skill/config metadata during updates.

🤖 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. 1 suggestion posted.

Fix All in Augment

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

const preservedModuleSet = new Set(preservedModules || []);
const ids = new Set();
for (const row of previousRows || []) {
if (row.canonicalId && !preservedModuleSet.has(row.module)) {
Copy link
Copy Markdown

@augmentcode augmentcode Bot May 18, 2026

Choose a reason for hiding this comment

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

In _getPreviousSkillIdsForCleanup, preservation depends on row.module being present in the previous skill-manifest.csv; if older manifests are missing the module column (or it’s blank), preserved-module skills could still be scheduled for cleanup. Consider a fallback derivation (e.g., from row.path) before comparing against preservedModules to make the stale-module compatibility path more robust.

Severity: medium

Other Locations
  • tools/installer/core/installer.js:455

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 78feb0cd-116d-450d-b8c1-e2b1a1c20d7f

📥 Commits

Reviewing files that changed from the base of the PR and between 0eae7c4 and 3cdee79.

📒 Files selected for processing (3)
  • tools/installer/core/installer.js
  • tools/installer/ide/_config-driven.js
  • tools/installer/ui.js

📝 Walkthrough

Walkthrough

The PR adds module preservation support to the installer's install/update flows. UI detects unselected installed modules lacking custom sources and marks them for preservation. The installer reads existing skill-manifest.csv before overwrite, excludes preserved modules from removal, tracks their files for manifest purposes, and re-appends their rows post-generation with deduping. IDE cleanup logic adjusts flow detection based on skill-ID truthiness.

Changes

Module Preservation During Install and Update

Layer / File(s) Summary
UI module preservation detection
tools/installer/ui.js
New _retainUnavailableInstalledModules() method identifies installed non-official modules to preserve when custom sources are unavailable. promptInstall() integrates this during update flow and includes _preserveModules in the return object.
Install entry point and skill-manifest reading
tools/installer/core/installer.js
install() threads originalConfig._preserveModules through _removeDeselectedModules() and _installAndConfigure(). It reads existing skill-manifest.csv rows and computes prior skill IDs to clean up while excluding preserved modules, passing previous rows forward.
Configuration generation and manifest restoration
tools/installer/core/installer.js
During configuration generation, preserved modules are tracked in installed files, module lists adjusted for manifest generation based on update vs full install, and preserved skill-manifest rows re-appended with CSV deduping. New helpers parse skill-manifest CSV, compute cleanup IDs, and append preserved rows with escaping.
IDE cleanup flow truthiness adjustment
tools/installer/ide/_config-driven.js
Removal-set selection and isInstallFlow flag now check previousSkillIds truthiness instead of requiring non-empty set size, adjusting cleanup behavior when skill IDs are empty or present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • bmad-code-org/BMAD-METHOD#2223: Both PRs modify the installer's update/skill-cleanup pipeline by reading and parsing existing _config/skill-manifest.csv to drive retention/removal decisions during install/quick-update flows.
  • bmad-code-org/BMAD-METHOD#2083: Both PRs modify manifest-generation CSV preservation logic; the main PR threads _preserveModules to retain skill-manifest rows while the retrieved PR removes earlier preservation logic.
  • bmad-code-org/BMAD-METHOD#2315: Both PRs extend installer cleanup/removal paths; the main PR preserves marked modules by canonicalId during update while the retrieved PR removes legacy pre-v6.2.0 wrapper skills.

Suggested reviewers

  • pbean
  • bmadcode
  • alexeyv
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: preserving stale installed modules during update operations, which is the core focus of the changeset.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the problem being solved and the changes made to preserve stale modules during updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

tools/installer/ide/_config-driven.js

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

tools/installer/core/installer.js

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

tools/installer/ui.js

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.


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.

@bmadcode bmadcode merged commit a085226 into bmad-code-org:main May 18, 2026
6 checks passed
bmadcode added a commit that referenced this pull request May 18, 2026
Documents the fix landed in #2391 and the manual step required for users
who installed the experimental BMad Automator module under its previous
`baut` code.
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.

2 participants