Skills › BMAD Method › bmad › resolve_config.py
resolve_config.py
84 lines · skills/bmad/scripts/resolve_config.py at bd70c64
1#!/usr/bin/env python3
2# /// script
3# requires-python = ">=3.11"
4# ///
5"""Resolve BMad's three central TOML layers to JSON."""
7import argparse
8import json
9import sys
10from pathlib import Path
12# Installed scripts are consumer files, not a location for interpreter caches.
13sys.dont_write_bytecode = True
15try:
16 from config_utils import ConfigError, load_central_config
17except ModuleNotFoundError as error:
18 if error.name != "tomllib":
19 raise
20 sys.stderr.write("error: Python 3.11+ is required (stdlib `tomllib` not found).\n")
21 raise SystemExit(3) from None
24_MISSING = object()
27def extract_key(data, dotted_key: str):
28 current = data
29 for part in dotted_key.split("."):
30 if isinstance(current, dict) and part in current:
31 current = current[part]
32 else:
33 return _MISSING
34 return current
37def write_json_stdout(output) -> None:
38 """Pin stdout to UTF-8 — a Windows cp1252 default cannot encode emoji icons."""
39 reconfigure = getattr(sys.stdout, "reconfigure", None)
40 if reconfigure is not None:
41 reconfigure(encoding="utf-8")
42 sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
45def main() -> int:
46 parser = argparse.ArgumentParser(description="Resolve BMad central config using three-layer TOML merge.")
47 parser.add_argument(
48 "--project-root",
49 "-p",
50 required=True,
51 help="Absolute project root containing _bmad/",
52 )
53 parser.add_argument(
54 "--key",
55 "-k",
56 action="append",
57 default=[],
58 help="Dotted field path to resolve (repeatable). Omit for full dump.",
59 )
60 args = parser.parse_args()
62 try:
63 merged = load_central_config(Path(args.project_root).resolve())
64 except ConfigError as error:
65 sys.stderr.write(f"error: {error}\n")
66 return 1
68 output = merged
69 if args.key:
70 output = {}
71 for key in args.key:
72 value = extract_key(merged, key)
73 if value is not _MISSING:
74 output[key] = value
75 write_json_stdout(output)
76 return 0
79if __name__ == "__main__":
80 if sys.platform == "win32":
81 # Piped output on Windows defaults to a legacy code page, not UTF-8.
82 sys.stdout.reconfigure(encoding="utf-8")
83 sys.stderr.reconfigure(encoding="utf-8")
84 raise SystemExit(main())