- channel-resolver: strip a trailing slash before `.git` so `…/r.git/` resolves
to repo `r` (was `r.git`, which broke stable-tag lookup).
- config-gen: drop orphaned [agents.*] blocks owned by this module (module=
fallback) on regenerate, not only those still in the current module.yaml.
- install-plan: only honor file sources for the fixed-file Claude surfaces
(hooks/mcpServers/lspServers/settings) so the rewritten manifest never points
at an uncopied file; anchor customize.schemas rewrites on the owning skill dir
so nested schema paths survive.
- cli: reject unknown flags with a usage error instead of running with defaults.
- project-root: prefer a resolution's exact moduleYamlPath over the first
module.yaml found under the repo root (multi-module repos).
- official-modules: read the flattened _bmad/<code>/module.yaml first so new-spec
modules honor their declared working directories.
- Add channel-resolver `.git/` regression cases.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bmad-module skill staged community modules under _bmad/<code>/ but never
pushed their skills out to the coding assistants the user selected at
`bmad install` time, so a freshly installed module was invisible to Claude
Code / Cursor / Copilot / etc. until a full reinstall; remove left skills
orphaned in the IDE dirs.
install/update/remove now distribute (or prune) skills to every IDE listed in
_bmad/_config/manifest.yaml and clean the redundant skill dirs from _bmad/,
matching how official modules end up.
Single engine, three callers — no fork:
- New tools/installer/core/ide-sync.js (syncIdes) wraps the real
IdeManager.setupBatch + platform-codes engine. The full installer
(_setupIdes/_cleanupSkillDirs), the new `bmad ide-sync` command, and the
skill all route through it, so new IDEs and engine changes propagate
everywhere automatically.
Local, dependency-free delivery — no npx/network at runtime:
- build-ide-sync.mjs esbuild-bundles the engine into vendor/ide-sync.mjs
(+ platform-codes.yaml), aliasing ../prompts and ../project-root to small
shims so @clack and the installer graph are dropped. The bundle ships inside
the skill tree (like yaml.mjs); the skill execs it locally. It's
generated-from-source and gated by vendor:check, refreshed on every install.
update/remove pass --prune with the module's canonicalIds so skills dropped
between versions (or on uninstall) are removed from IDE dirs + command
pointers. Graceful degradation: if the bundle is unreachable, the verb still
succeeds and points the user at `bmad ide-sync`.
Tests: new test/test-ide-sync.js drift-guard (engine == bundle, incl. prune),
integration.test.sh IDE-distribution section (offline), bundle self-check in
the build. All gates green (vendor:check, lint, format, test:install 349/349).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>