Skip to content

fix(installer): simplify install summary#1915

Merged
alexeyv merged 3 commits intobmad-code-org:mainfrom
alexeyv:fix/installer-summary-skills
Mar 12, 2026
Merged

fix(installer): simplify install summary#1915
alexeyv merged 3 commits intobmad-code-org:mainfrom
alexeyv:fix/installer-summary-skills

Conversation

@alexeyv
Copy link
Copy Markdown
Collaborator

@alexeyv alexeyv commented Mar 12, 2026

Summary

  • simplify the final install summary to keep only BMAD, selected modules, selected IDE output, and explicit no-IDE wording for _bmad-only installs
  • remove low-value internal noise such as manifests, help catalog, generated configurations, and module directory lines from the final install summary
  • count skill-format IDE installs by unique installed skill directories and report user-facing totals as overlapping skills and agents

Verification

  • node test/test-installation-components.js (passed in /Users/alex/src/bmad/main before branching)
  • manual install check with --tools antigravity
  • manual install check with --tools none
  • targeted check confirmed skill-format detail renders as 2 skills, 2 agents

@augmentcode
Copy link
Copy Markdown

augmentcode bot commented Mar 12, 2026

🤖 Augment PR Summary

Summary: This PR simplifies the installer’s final summary output and fixes skill-format install reporting to avoid double-counting when multiple artifacts map to the same skill directory.

Changes:

  • Installer summary now shows only BMAD, selected modules, and selected IDE steps (plus any warnings/errors), and renames CoreBMAD
  • Adds explicit “No IDE selected (installed in _bmad only)” messaging for _bmad-only installs
  • Config-driven IDE setups track and report unique skill directories written via a Set (skillDirectories)
  • IDE manager detail strings prefer skillDirectories for skill-format installs
  • Adds a regression test fixture covering overlapping skill names and asserting unique directory counting

Technical Notes: Unique skill counting is based on directory names written during setup, so collisions (e.g., workflow-skill + verbatim skill with same canonicalId) report once while preserving existing per-artifact counters.

🤖 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. 2 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 12, 2026

📝 Walkthrough

Walkthrough

This PR introduces per-skill write tracking and skill-directory count reporting to the IDE installer system. It adds a new test suite validating skill collision scenarios, enhances install summary rendering with dynamic step labeling, implements a skillWriteTracker in the config-driven installer to count skill files created, and modifies the result reporting to prioritize skillDirectories counts when available.

Changes

Cohort / File(s) Summary
Test Suite for Skill Collision
test/test-installation-components.js
Added Test Suite 31 with createSkillCollisionFixture helper to validate skill count reporting and collision handling. Tests verify skillDirectories count (2 skills), overlapping skill directories created once, and proper agent skill directory structure. Suite runs twice in the file (duplicate blocks).
Installer Core Summary Rendering
tools/cli/installers/lib/core/installer.js
Enhanced renderInstallSummary to compute dynamic stepLabel: relabel "Core" as "BMAD", prefix "Module: " steps as-is, match step to selected IDEs. Removed Manifests entry. Added fallback message for no IDE selection. Skip lines without applicable stepLabel.
Skill Write Tracking
tools/cli/installers/lib/ide/_config-driven.js
Introduced skillWriteTracker to count per-skill write operations during installation. Tracker incremented in writeSkillFile and installVerbatimSkills paths. Summary output now prefers skillDirectories count when available, with fallback to agents/workflows/tasks/tools/skills counts.
Result Reporting
tools/cli/installers/lib/ide/manager.js
Added new reporting logic: if r.skillDirectories > 0, report that count as "skills" detail string, bypassing older artifact counting. Preserves backward compatibility by falling back to original fields when skillDirectories not present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • bmadcode
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(installer): simplify install summary' accurately summarizes the main change—simplifying the installer's summary output. It is concise, clear, and directly reflects the core objective of the PR.
Description check ✅ Passed The pull request description clearly outlines the changes: simplifying install summary output, removing low-value internal noise, and counting skill-format installs by unique directories. It directly relates to the changeset modifications across installer files and tests.

✏️ 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
📝 Coding Plan for PR comments
  • Generate coding plan

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tools/cli/installers/lib/ide/_config-driven.js (1)

132-167: ⚠️ Potential issue | 🟠 Major

Keep skillWriteTracker local to a single install run.

IdeManager reuses one handler instance per platform, but this Set is stored on the handler and then mutated later by writeSkillFile() and installVerbatimSkills(). Two overlapping setup() calls on the same IDE will share and clear the same tracker, so skillDirectories and summary output can bleed across installs. Pass a local Set through the call chain instead of hanging per-run state on this; at minimum, clear it in a finally.

🤖 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 132 - 167, The
current this.skillWriteTracker is shared across handler instances and causes
bleed between overlapping installs; instead create a local Set (e.g., const
skillWriteTracker = config.skill_format ? new Set() : null) inside the
install/setup call and pass that Set into installVerbatimSkills(...) and
writeSkillFile(...) (update those method signatures/call sites to accept the
tracker), use skillWriteTracker.size for results.skillDirectories, and remove
reliance on this.skillWriteTracker; if you cannot change all call sites
immediately, ensure the field is cleared in a finally block after await
this.printSummary(...) to avoid cross-run leakage.
🧹 Nitpick comments (5)
test/test-installation-components.js (3)

1848-1852: These assertions are pinning intermediate bookkeeping, not the contract.

The behavior this PR changes is the unique directory count (detail / skillDirectories). Exact results.agents, results.workflows, and results.skills values come from _config-driven.js internals and will break on harmless generator refactors. I'd keep the assertions on unique directories and on-disk paths, and drop the incidental per-bucket counts unless you intend them to be stable.

🤖 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 1848 - 1852, The tests are
asserting internal bookkeeping values (result.handlerResult.results.agents,
.workflows, .skills) which are not part of the public contract and may change
with generator refactors; remove or replace those three assertions and keep only
the assertions that check the unique directory count (result.detail and
result.handlerResult.results.skillDirectories) and any assertions that validate
on-disk paths/installed skill directories; specifically, delete or comment out
the lines asserting results.agents, results.workflows, and results.skills and
ensure the test still verifies unique skill directory behavior via result.detail
and skillDirectories and any filesystem path checks.

90-117: Avoid hand-writing manifest CSV schemas in this fixture.

These inline headers duplicate production manifest formats by hand. The next schema change in agent-manifest.csv, workflow-manifest.csv, or skill-manifest.csv will make this regression drift away from the real installer inputs. Reuse ManifestGenerator or a shared fixture helper so the test stays aligned with production.

🤖 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 90 - 117, The test is
hand-writing CSV manifest headers and rows for agent-manifest.csv,
workflow-manifest.csv, and skill-manifest.csv which will drift from production
schemas; replace the manual fs.writeFile calls in
test/test-installation-components.js with the shared ManifestGenerator (or the
existing fixture helper) to produce these manifests (use the generator to emit
agent, workflow, and skill manifests with the same sample entries currently
present), updating references to the generated file paths instead of the
hard-coded CSV strings so the test remains in sync with production schema
changes.

1853-1857: Assert which colliding bmad-help content is supposed to survive.

This fixture deliberately creates a workflow/native-skill name collision, but the test only checks that the directory exists. Add a content assertion on .agent/skills/bmad-help/SKILL.md so the suite locks down the intended overwrite precedence instead of just the count.

🤖 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 1853 - 1857, The test
currently only asserts the existence of .agent/skills/bmad-help/SKILL.md; update
it to also assert the actual file content to lock down which source wins the
collision by reading the file at '.agent/skills/bmad-help/SKILL.md' and
comparing its contents against the expected SKILL.md from the fixture that
should take precedence (i.e., the workflow or the native-skill fixture);
implement this by using fs.readFile or fs.readFileSync and an assert.strictEqual
(or assert.include) to compare to the expected fixture content so the test fails
if the wrong variant survived.
tools/cli/installers/lib/core/installer.js (1)

1389-1391: Use IDE display names in this final note, not platform keys.

Successful IDE rows are still labeled with internal IDs like github-copilot and rovo-dev. Since this summary is user-facing, it should render each handler's displayName instead.

🤖 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 1389 - 1391, The
final note is using internal platform keys (e.g., r.step / selectedIdes entries)
as labels; change it to use each IDE handler's user-facing displayName instead:
when you set stepLabel (currently in the branch that checks
selectedIdes.has(String(r.step).toLowerCase())), look up the corresponding
handler by the internal id (r.step) and assign handler.displayName to stepLabel
(fall back to r.step only if displayName is missing). Update any logic that
compares against selectedIdes or lowercased ids to still find the handler (use
the same id normalization) but render displayName in the summary.
tools/cli/installers/lib/ide/manager.js (1)

165-173: Extract the install-result formatter into one shared helper.

This precedence rule now exists here and again in tools/cli/installers/lib/ide/_config-driven.js:715-723. The next tweak to skill reporting will drift one of them. Centralize the formatter and reuse it for both detail and the console summary.

🤖 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 165 - 173, Extract the
repeated precedence logic into a single helper function (e.g.,
formatInstallResult(result) or formatInstallResultSummary) that accepts the
install result object (r) and returns the parts/summary string; replace the
duplicated block in manager.js (the if (r.skillDirectories > 0) ... else ...)
and the matching block in _config-driven.js with calls to this new helper, and
export/import the helper so both the detail renderer and the console summary use
the same implementation.
🤖 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 1827-1863: Add an automated test that exercises the
no-IDE/"--tools none" install-summary branch so
Installer.renderInstallSummary()'s _bmad-only path is covered: invoke
IdeManager.setup(...) with the same fixture used elsewhere but pass the options
that simulate no IDE/tools (e.g. tools: 'none' or the equivalent flag used by
Installer) so the Installer.renderInstallSummary() code path is executed, then
assert the returned summary/detail string contains the expected _bmad-only
wording and any handlerResult fields the PR changed; place this alongside the
existing Skill Count test and reference IdeManager.setup and
Installer.renderInstallSummary in the test to ensure the specific branch is hit.
- Around line 84-86: The helper createSkillCollisionFixture leaks the outer temp
directory because mkdtemp() creates fixtureRoot but only the child fixtureDir
(_bmad) is removed; update createSkillCollisionFixture to either create the BMAD
fixture directly in the temporary directory returned by mkdtemp (so fixtureRoot
=== fixtureDir) or return fixtureRoot to the caller so the caller can clean it
up; ensure references to fixtureRoot, fixtureDir and the mkdtemp call are
adjusted so the created temp root is the one removed in the test teardown.

In `@tools/cli/installers/lib/core/installer.js`:
- Around line 1409-1410: The summary currently hardcodes '_bmad' and always
includes an IDE-only footer even when (context.ides || []).length === 0; update
the branch that pushes the "No IDE selected" message to use BMAD_FOLDER_NAME
instead of the literal '_bmad' and make the footer that tells the user to run
`bmad-help` conditional on there being at least one IDE selected (i.e., the same
check using context.ides). Locate and modify the lines around the "No IDE
selected" push and the footer emission code so the footer is emitted only when
context.ides has items and the folder name is referenced via BMAD_FOLDER_NAME.

---

Outside diff comments:
In `@tools/cli/installers/lib/ide/_config-driven.js`:
- Around line 132-167: The current this.skillWriteTracker is shared across
handler instances and causes bleed between overlapping installs; instead create
a local Set (e.g., const skillWriteTracker = config.skill_format ? new Set() :
null) inside the install/setup call and pass that Set into
installVerbatimSkills(...) and writeSkillFile(...) (update those method
signatures/call sites to accept the tracker), use skillWriteTracker.size for
results.skillDirectories, and remove reliance on this.skillWriteTracker; if you
cannot change all call sites immediately, ensure the field is cleared in a
finally block after await this.printSummary(...) to avoid cross-run leakage.

---

Nitpick comments:
In `@test/test-installation-components.js`:
- Around line 1848-1852: The tests are asserting internal bookkeeping values
(result.handlerResult.results.agents, .workflows, .skills) which are not part of
the public contract and may change with generator refactors; remove or replace
those three assertions and keep only the assertions that check the unique
directory count (result.detail and
result.handlerResult.results.skillDirectories) and any assertions that validate
on-disk paths/installed skill directories; specifically, delete or comment out
the lines asserting results.agents, results.workflows, and results.skills and
ensure the test still verifies unique skill directory behavior via result.detail
and skillDirectories and any filesystem path checks.
- Around line 90-117: The test is hand-writing CSV manifest headers and rows for
agent-manifest.csv, workflow-manifest.csv, and skill-manifest.csv which will
drift from production schemas; replace the manual fs.writeFile calls in
test/test-installation-components.js with the shared ManifestGenerator (or the
existing fixture helper) to produce these manifests (use the generator to emit
agent, workflow, and skill manifests with the same sample entries currently
present), updating references to the generated file paths instead of the
hard-coded CSV strings so the test remains in sync with production schema
changes.
- Around line 1853-1857: The test currently only asserts the existence of
.agent/skills/bmad-help/SKILL.md; update it to also assert the actual file
content to lock down which source wins the collision by reading the file at
'.agent/skills/bmad-help/SKILL.md' and comparing its contents against the
expected SKILL.md from the fixture that should take precedence (i.e., the
workflow or the native-skill fixture); implement this by using fs.readFile or
fs.readFileSync and an assert.strictEqual (or assert.include) to compare to the
expected fixture content so the test fails if the wrong variant survived.

In `@tools/cli/installers/lib/core/installer.js`:
- Around line 1389-1391: The final note is using internal platform keys (e.g.,
r.step / selectedIdes entries) as labels; change it to use each IDE handler's
user-facing displayName instead: when you set stepLabel (currently in the branch
that checks selectedIdes.has(String(r.step).toLowerCase())), look up the
corresponding handler by the internal id (r.step) and assign handler.displayName
to stepLabel (fall back to r.step only if displayName is missing). Update any
logic that compares against selectedIdes or lowercased ids to still find the
handler (use the same id normalization) but render displayName in the summary.

In `@tools/cli/installers/lib/ide/manager.js`:
- Around line 165-173: Extract the repeated precedence logic into a single
helper function (e.g., formatInstallResult(result) or
formatInstallResultSummary) that accepts the install result object (r) and
returns the parts/summary string; replace the duplicated block in manager.js
(the if (r.skillDirectories > 0) ... else ...) and the matching block in
_config-driven.js with calls to this new helper, and export/import the helper so
both the detail renderer and the console summary use the same implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d94bfda8-2492-4299-a42a-1199320477ed

📥 Commits

Reviewing files that changed from the base of the PR and between 32693f1 and 83b0387.

📒 Files selected for processing (4)
  • 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/manager.js

@bmadcode
Copy link
Copy Markdown
Collaborator

@alexeyv if you do this one, if not already, please remove the count of tools and other things so its just total skills and total agents

alexeyv and others added 2 commits March 12, 2026 07:42
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Return fixture root from createSkillCollisionFixture so cleanup
  removes the parent temp directory, not just the _bmad child
- Only show bmad-help next-step line when IDEs are configured
@alexeyv
Copy link
Copy Markdown
Collaborator Author

alexeyv commented Mar 12, 2026

Triage Summary — Review Findings

Inline threads (all resolved above):

  • F2 (temp dir leak) — FIX applied in 0071f1c
  • F3 (no --tools none test) — REJECT, no separate code path exists
  • F4 (no-IDE footer contradiction) — FIX applied in 0071f1c

Review body findings:

  • F1 [MAJOR] skillWriteTracker shared state bleed — REJECT. No skillWriteTracker property exists on this; all skill-related state is function-local. False positive from CodeRabbit.

Auto-dismissed (LOW severity, noise):

  • Assertions pin internal bookkeeping values — standard regression assertions for a new test
  • Hand-writing manifest CSV schemas — normal test fixture setup
  • Assert collision content, not just existence — existence check sufficient for this PR scope
  • Use IDE displayName, not platform keys — cosmetic, not a bug
  • Extract install-result formatter into shared helper — refactoring suggestion, out of scope

@alexeyv alexeyv merged commit c575064 into bmad-code-org:main Mar 12, 2026
5 checks passed
@alexeyv alexeyv deleted the fix/installer-summary-skills branch March 12, 2026 14:40
alexeyv added a commit to alexeyv/BMAD-METHOD that referenced this pull request Mar 13, 2026
* fix(installer): simplify install summary

* style: fix prettier formatting in test file

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(installer): clean up temp dir leak and conditional IDE footer

- Return fixture root from createSkillCollisionFixture so cleanup
  removes the parent temp directory, not just the _bmad child
- Only show bmad-help next-step line when IDEs are configured

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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