Commit Graph

2 Commits

Author SHA1 Message Date
Brian Madison 579c78d2aa fix(installer): address code-review findings on config refactor
Nine fixes covering bugs caught by my code-review, Augment, and CodeRabbit:

quickUpdate identity overwrite (official-modules.js): collectModuleConfigQuick
now lazy-loads globalConfig and falls back through ~/.bmad/config.user.toml
before getDefaultUsername(), so `bmad update` no longer silently overwrites
the user's global identity with the OS username.

computeProcessedDefault placeholder asymmetry (manifest-generator.js): build
a shipped-defaults crossKeyDefaults map and feed BOTH writeCentralConfig and
writeModuleTomls through it. Previously stripDefaults resolved {output_folder}
against user answers while module.toml resolved it against shipped defaults —
overriding output_folder silently reverted every derived path on read.

parseTomlScalar escape order (global-config.js): single-pass regex replacer
so `\\n` round-trips as backslash+n instead of collapsing to a newline.
Windows paths and any TOML string with literal `\n`/`\t`/`\r` survive.

writeGlobalUserCore nested-table corruption (manifest-generator.js): emit
nested objects as proper dotted sub-tables (`[modules.bmm]`) instead of
serializing them as `"[object Object]"` strings inside the parent section.

extractAgentBlocks dead code (manifest-generator.js): deleted. The agent
preservation invariant was intentionally retired by Task F (agents live in
module.toml floor); the function had no callers.

applySetOverrides 3-tier routing (set-overrides.js): consults
~/.bmad/config.user.toml first, then project config.user.toml, then routes
known core scope:user keys (user_name, communication_language per core
schema) to global when neither file owns them. Prevents
`bmad install --set core.user_name=Alice` from polluting project team config.

BMAD_HOME tilde expansion (global-config.js): JS resolver now matches
Python's Path.expanduser() so installer and resolver agree on the global
location when BMAD_HOME is set in non-shell contexts (.env, Docker, Windows).

resolve_config.py fail-fast (resolve_config.py): when --project-root is
explicitly passed but _bmad/ doesn't exist, exit 1 with a clear error
instead of silently returning {}. Global-only mode (no --project-root)
remains permissive.

_MODULE_SKILLS_RE hyphen support (resolve_customization.py): allow hyphens
in module slugs (e.g. `foo-bar-skills/`) so qualified-name skill matching
works for hyphenated modules.

Tests: 383 JS tests + 21 Python tests pass; lint, markdownlint, prettier all
green. Suite 44 now isolates BMAD_HOME and asserts the new 3-tier routing
contract for `--set` overrides.
2026-05-25 23:52:24 -05:00
Brian Madison bec2c04a6d feat(installer): cross-platform global config + lean per-project overrides
Phase 1 of the config refactor. Splits configuration into three clearly-owned
layers and removes per-install duplication:

- Global tier (~/.bmad/, $BMAD_HOME override): one-time identity + machine-wide
  defaults. config.user.toml holds scope:user core answers (user_name, language)
  so they're asked once per machine, not once per project.
- Per-module shipped-defaults floor (_bmad/{module}/module.toml): regenerated
  every install; the resolver's lowest-priority layer.
- Project overrides (_bmad/config.toml): lean — only emits deltas from module
  defaults. No more [agents.X] sections (agents live in module.toml floor).

Resolver chain (src/scripts/resolve_config.py) is now 7 tiers and supports
global-only operation (no _bmad/config.toml required). Customization cascade
(resolve_customization.py) splits cleanly from config: customize.toml files at
global, project, and custom tiers; never reads config.toml.

Installer (tools/installer/):
- New global-config.js: cross-platform resolver + dependency-free TOML reader.
- official-modules.js: silently reuses scope:user globals; logs a friendly note
  showing what was reused/seeded and where to edit it.
- manifest-generator.js: writes per-module module.toml with placeholder
  resolution for cross-key references (e.g. {output_folder}); routes core
  scope:user answers to ~/.bmad/config.user.toml.
- Removed --ask flag.

Tests: 11 new Python resolver tests, 8 new customization-cascade tests,
suites 35/37/38/45/46 in test-installation-components.js updated/added for the
new contract (with BMAD_HOME isolation to avoid touching real ~/.bmad).
2026-05-25 23:05:18 -05:00